token handling fix for bytes32 results

This commit is contained in:
Tim
2024-03-19 12:11:18 -04:00
parent 7ec9af3e6d
commit 9d9b53327b
3 changed files with 24 additions and 13 deletions

View File

@@ -8,6 +8,8 @@ from ..base.chain import current_chain
def get_contract_data(name):
if name in abis:
return {'abi':abis[name]}
if name == "Vault" and os.path.exists(f'../contract/out/I{name}.sol/I{name}.json') :
# logging.debug("getting abi from IVault.json instead of Vault.json")
name = "IVault" # Special case for proxy Vault

View File

@@ -1,5 +1,5 @@
abis = {
# ERC20 where symbol() returns a bytes32 instead of a string
'ERC20.sb': '''[{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"}]'''
'ERC20.sb': '''[{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"}]'''
# 'WMATIC': '''[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}]''',
}

View File

@@ -27,26 +27,35 @@ async def get_token(address) -> Optional[TokenDict]:
async def load_token(address: str) -> Optional[TokenDict]:
contract = ERC20(address)
name_prom = contract.name()
dec_prom = contract.decimals()
async def get_string_or_bytes32(func_name):
try:
symbol = await contract.symbol()
except (InsufficientDataBytes, BadFunctionCallOutput):
result = await getattr(contract, func_name)()
except (InsufficientDataBytes, BadFunctionCallOutput, OverflowError):
# this happens when the token returns bytes32 instead of a string
try:
symbol = await ContractProxy(address, 'ERC20.sb').symbol()
log.info(f'got bytes32 symbol {symbol}')
rb: bytes = await ContractProxy(address, 'ERC20.sb').symbol()
end = rb.find(b'\x00')
if end == -1:
end = 32
result = rb[:end].decode('utf8')
except (InsufficientDataBytes, ContractLogicError, BadFunctionCallOutput):
log.warning(f'token {address} has broken symbol()')
log.warning(f'token {address} has broken {func_name}()')
return None
return result
dec_prom = contract.decimals()
symbol_prom = get_string_or_bytes32('symbol')
name_prom = get_string_or_bytes32('name')
try:
decimals = await dec_prom
except (InsufficientDataBytes, ContractLogicError, BadFunctionCallOutput):
log.warning(f'token {address} has no decimals()')
decimals = 0
name = await name_prom
approved = config.metadata is None
chain_id = current_chain.get().chain_id
symbol = await symbol_prom
name = await name_prom
td = TokenDict(type='Token', chain=chain_id, address=address,
name=name, symbol=symbol, decimals=decimals, approved=approved)
md = get_metadata(address, chain_id=chain_id)