Module: PolarLoop::Abi
- Defined in:
- lib/polarloop/abi.rb
Constant Summary collapse
- ABI_PATH =
File.("abi/polar_loop.json", __dir__)
- OPERATOR_ROLE =
keccak256("OPERATOR_ROLE") — matches Solidity keccak256("OPERATOR_ROLE")
Eth::Util.keccak256("OPERATOR_ROLE")
- DEFAULT_ADMIN_ROLE =
bytes32(0) — DEFAULT_ADMIN_ROLE in AccessControl
"\x00" * 32
- MANDATE_CREATED_TOPIC =
Event topic hashes (keccak256 of event signature)
Eth::Util.keccak256( "MandateCreated(bytes32,address,address,address,uint128,uint32,uint128,bytes32)" )
- MANDATE_CHARGED_TOPIC =
Eth::Util.keccak256( "MandateCharged(bytes32,address,address,uint128,uint48)" )
- MANDATE_REVOKED_TOPIC =
Eth::Util.keccak256( "MandateRevoked(bytes32,address)" )
- ERROR_STRING_SELECTOR =
Standard Solidity error selectors (not in ABI)
"08c379a0"- PANIC_SELECTOR =
Error(string) — require(false, "msg")
"4e487b71"
Class Method Summary collapse
- .abi ⇒ Object
-
.decode_revert(hex_data) ⇒ Object
Decode hex revert data into human-readable error string.
-
.error_selectors ⇒ Object
Precomputed error selectors from ABI for decoding revert data.
- .topic_hex(topic) ⇒ Object
Class Method Details
.abi ⇒ Object
9 10 11 |
# File 'lib/polarloop/abi.rb', line 9 def self.abi @abi ||= JSON.parse(File.read(ABI_PATH)) end |
.decode_revert(hex_data) ⇒ Object
Decode hex revert data into human-readable error string
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/polarloop/abi.rb', line 50 def self.decode_revert(hex_data) return nil unless hex_data.is_a?(String) && hex_data.sub(/\A0x/i, "").length >= 8 raw = hex_data.sub(/\A0x/i, "") selector = raw[0, 8] # Standard Error(string) if selector == ERROR_STRING_SELECTOR encoded = [raw[8..]].pack("H*") decoded = Eth::Abi.decode(["string"], encoded) return decoded[0] end # Standard Panic(uint256) if selector == PANIC_SELECTOR encoded = [raw[8..]].pack("H*") decoded = Eth::Abi.decode(["uint256"], encoded) return "Panic(0x#{decoded[0].to_s(16).rjust(2, '0')})" end # Custom errors from contract ABI error_info = error_selectors[selector] return "Unknown error (0x#{selector})" unless error_info return error_info[:name] if error_info[:types].empty? encoded = [raw[8..]].pack("H*") decoded = Eth::Abi.decode(error_info[:types], encoded) args = decoded.map do |v| if v.is_a?(String) && v.encoding == Encoding::BINARY "0x" + v.unpack1("H*") else v.to_s end end "#{error_info[:name]}(#{args.join(', ')})" rescue "Unknown error: #{hex_data}" end |
.error_selectors ⇒ Object
Precomputed error selectors from ABI for decoding revert data
37 38 39 40 41 42 43 |
# File 'lib/polarloop/abi.rb', line 37 def self.error_selectors @error_selectors ||= abi.select { |e| e["type"] == "error" }.each_with_object({}) do |entry, hash| sig = "#{entry["name"]}(#{(entry["inputs"] || []).map { |i| i["type"] }.join(",")})" selector = Eth::Util.keccak256(sig)[0, 4].unpack1("H*") hash[selector] = { name: entry["name"], types: (entry["inputs"] || []).map { |i| i["type"] } } end end |
.topic_hex(topic) ⇒ Object
32 33 34 |
# File 'lib/polarloop/abi.rb', line 32 def self.topic_hex(topic) "0x" + topic.unpack1("H*") end |