It looks like they actually follow a concept of "Universes", and each universe is an instance of the following:
contract Delegator is DelegationTarget {
function Delegator(IController _controller, bytes32 _controllerLookupName) public {
controller = _controller;
controllerLookupName = _controllerLookupName;
}
function() external payable {
// Do nothing if we haven't properly set up the delegator to delegate calls
if (controllerLookupName == 0) {
return;
}
// Get the delegation target contract
address _target = controller.lookup(controllerLookupName);
assembly {
//0x40 is the address where the next free memory slot is stored in Solidity
let _calldataMemoryOffset := mload(0x40)
// new "memory end" including padding. The bitwise operations here ensure we get rounded up to the nearest 32 byte boundary
let _size := and(add(calldatasize, 0x1f), not(0x1f))
// Update the pointer at 0x40 to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
mstore(0x40, add(_calldataMemoryOffset, _size))
// Copy method signature and parameters of this call into memory
calldatacopy(_calldataMemoryOffset, 0x0, calldatasize)
// Call the actual method via delegation
let _retval := delegatecall(gas, _target, _calldataMemoryOffset, calldatasize, 0, 0)
switch _retval
case 0 {
// 0 == it threw, so we revert
revert(0,0)
} default {
// If the call succeeded return the return data from the delegate call
let _returndataMemoryOffset := mload(0x40)
// Update the pointer at 0x40 again to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
mstore(0x40, add(_returndataMemoryOffset, returndatasize))
returndatacopy(_returndataMemoryOffset, 0x0, returndatasize)
return(_returndataMemoryOffset, returndatasize)
}
}
}
}
As you can see, it is simply a proxy contract that uses delegate call to invoke functions on the address returned by the controller. Your actual functions such as balanceOf
will be defined on the target contract.
Call()
to the contract, and check its output and error , if it produces an error I flag the contract as non-compliant. Your results prove I have chosen the right way, though I thought of checking for signatures too. – Nulik Sep 7 '18 at 13:59totalSupply
method exists +name
method exists +symbol
method exists +balanceOf
method exists. Even if they return null values I am still considering them as ERC20 – Nulik Sep 7 '18 at 14:03