Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abi decode value returned as [Getter] and throws error when accessing it #1361

Closed
miguelmota opened this issue Mar 15, 2021 · 5 comments
Closed
Labels
discussion Questions, feedback and general information.

Comments

@miguelmota
Copy link

miguelmota commented Mar 15, 2021

Hi,

I'm trying to decode function data but geting an unexpected result. This ABI has two input types so the expected result is an array with two values. The result array is indeed length of 2, however the first item is returned as [Getter] function instead of returning the address value.

const ethers = require('ethers')
const fragment = { constant: false, inputs: [{ name: '_to', type: 'address' }, { name: '_value', type: 'uint256' }], name: 'transfer', outputs: [{ name: 'success', type: 'bool' }], payable: false, type: 'function' }

const ifc = new ethers.utils.Interface([])
const data = '0xa9059cbb85f1150654584d0192059454e9dc1532d9d9cf914926406a02370cea80cf32f600000000000000000000000000000000000000000000000000000000033dc10b'
const result = ifc.decodeFunctionData(ethers.utils.FunctionFragment.fromObject(fragment), data)
console.log(result)
console.log(result.length)
console.log(result[0])
[
  [Getter],
  BigNumber { _hex: '0x033dc10b', _isBigNumber: true },
  _value: BigNumber { _hex: '0x033dc10b', _isBigNumber: true }
]
2
/home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/coders/array.js:163
                get: function () { throw value; }
                                   ^

_to: value out of range (argument="value", value=20, code=INVALID_ARGUMENT, version=bytes/5.0.11)
    at Logger.makeError (/home/mota/Sandbox/test/node_modules/@ethersproject/logger/lib/index.js:180:21)
    at Logger.throwError (/home/mota/Sandbox/test/node_modules/@ethersproject/logger/lib/index.js:189:20)
    at Logger.throwArgumentError (/home/mota/Sandbox/test/node_modules/@ethersproject/logger/lib/index.js:192:21)
    at Object.hexZeroPad (/home/mota/Sandbox/test/node_modules/@ethersproject/bytes/lib/index.js:264:16)
    at AddressCoder.decode (/home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/coders/address.js:40:45)
    at /home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/coders/array.js:109:31
    at Array.forEach (<anonymous>)
    at Object.unpack (/home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/coders/array.js:88:12)
    at TupleCoder.decode (/home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/coders/tuple.js:74:49)
    at AbiCoder.decode (/home/mota/Sandbox/test/node_modules/ethers/node_modules/@ethersproject/abi/lib/abi-coder.js:100:22) {
  reason: 'value out of range',
  code: 'INVALID_ARGUMENT',
  argument: 'value',
  value: 20,
  baseType: 'address',
  type: 'address'
}

Tx for reference: https://etherscan.io/tx/0x0fc8f1cb5112c4679dfcbde54306cabecedfbfd115030252b2e3d77ed7b7da8c

DeepinScreenshot_select-area_20210314182221

Etherscan is able to decode it correctly

DeepinScreenshot_select-area_20210314182214

@ricmoo
Copy link
Member

ricmoo commented Mar 15, 2021

A Result object uses a getter to defer access errors, for when the value is invalid for the type. Otherwise the decoding would fail immediately and error recovery would be impossible.

In your above example, you can see the data is an invalid address, as there are non-zero bytes in the top 12 bytes of what you are trying to interpret as an address. An ABI encoded address must have all its upper 96 bits zero.

The contract seems to have a bug in it? Was it written in assembly directly? Or perhaps the contract contains an asm block that is corrupting the return memory space?

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Mar 15, 2021
@miguelmota
Copy link
Author

miguelmota commented Mar 15, 2021

Not sure about the implementation details of the contract since it's not something I wrote.
Is it possible to access the the data for the input parameter to be able to truncate it manually? For example, If I were to wrap it an try catch and if it throws then check the field type and if it's an address type then try to truncate it and checksum it. Is this possible?

@armagg
Copy link

armagg commented May 3, 2021

do you have an update?
I faced with this error in decoding tron trx data for some of them ( about 30 percent)

@realarlong
Copy link

can you find any solution?

@ricmoo
Copy link
Member

ricmoo commented Aug 24, 2021

Yes, that it the entire point of that getter. It allows access to a value which would have otherwise fully crashed parsing. :)

If you look at the error, it contains the entire data used, which caused the problem, which can be used, for example, with toUtf8String, but with a folding error handler.

See #1894 for a code example which does exactly this. :)

@ethers-io ethers-io locked and limited conversation to collaborators Aug 24, 2021
@ricmoo ricmoo closed this as completed Aug 24, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
discussion Questions, feedback and general information.
Projects
None yet
Development

No branches or pull requests

4 participants