Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x38699d04656fF537ef8671b6b595402ebDBdf6f4
Balance 0 ETH
Nonce 1
Code Size 2351 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

2351 bytes
0x6080604052600436106100775763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166342cde4e88114610079578063a0ab9653146100a0578063aa5df9e2146101cc578063affe39c114610200578063affed0e014610265578063f3182e851461027a575b005b34801561008557600080fd5b5061008e61029e565b60408051918252519081900360200190f35b3480156100ac57600080fd5b506040805160206004803580820135838102808601850190965280855261007795369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a8935600160a060020a03169a8a8301359a9199909850606090910196509194509081019250819084018382808284375094975050508335600160a060020a03169450505060209091013590506102a4565b3480156101d857600080fd5b506101e4600435610627565b60408051600160a060020a039092168252519081900360200190f35b34801561020c57600080fd5b5061021561064f565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610251578181015183820152602001610239565b505050509050019250505060405180910390f35b34801561027157600080fd5b5061008e6106b2565b34801561028657600080fd5b506100776004803590602480359081019101356106b8565b60015481565b6000806000806000806001548d511415156102be57600080fd5b8b518d511480156102d057508d518d51145b15156102db57600080fd5b600160a060020a0388163314806102f95750600160a060020a038816155b151561030457600080fd5b7f3ee892349ae4bbe61dce18f95115b5dc02daf49204cc602458cd4c1f540d56d76001028b8b8b6040518082805190602001908083835b6020831061035a5780518252601f19909201916020918201910161033b565b518151600019602094850361010090810a9190910191821691199290921617909152604080519590930185900385206000548684019b909b52600160a060020a03998a16868501526060860198909852608085019790975260a0840198909852958f1660c08301525060e08082018e9052855180830390910181529301938490525050805190928291908401908083835b6020831061040a5780518252601f1990920191602091820191016103eb565b51815160209384036101000a6000190180199092169116179052604080519290940182900382206004547f19010000000000000000000000000000000000000000000000000000000000008484015260228401526042808401829052855180850390910181526062909301948590528251909c509195509293508392850191508083835b602083106104ad5780518252601f19909201916020918201910161048e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020945060009350600092505b6001548310156105f1576001858f8581518110151561050057fe5b906020019060200201518f8681518110151561051857fe5b906020019060200201518f8781518110151561053057fe5b60209081029091018101516040805160008082528185018084529790975260ff9095168582015260608501939093526080840152905160a0808401949293601f19830193908390039091019190865af1158015610591573d6000803e3d6000fd5b50505060206040510351915083600160a060020a031682600160a060020a03161180156105d65750600160a060020a03821660009081526002602052604090205460ff165b15156105e157600080fd5b81935082806001019350506104e5565b5060008054600101815588518190819060208c018d8f8cf1905080151561061757600080fd5b5050505050505050505050505050565b600380548290811061063557fe5b600091825260209091200154600160a060020a0316905081565b606060038054806020026020016040519081016040528092919081815260200182805480156106a757602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610689575b505050505090505b90565b60005481565b3330146106c457600080fd5b6106fb8383838080602002602001604051908101604052809392919081815260200183836020028082843750610700945050505050565b505050565b6000806014835111158015610716575082518411155b80156107225750600084115b151561072d57600080fd5b600091505b6003548210156107915760006002600060038581548110151561075157fe5b600091825260208083209190910154600160a060020a031683528201929092526040019020805460ff191691151591909117905560019190910190610732565b5060009050805b82518210156108415780600160a060020a031683838151811015156107b957fe5b60209081029091010151600160a060020a0316116107d657600080fd5b60016002600085858151811015156107ea57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff1916911515919091179055825183908390811061082a57fe5b602090810290910101516001909201919050610798565b8251610854906003906020860190610860565b50505060019190915550565b8280548282559060005260206000209081019282156108c2579160200282015b828111156108c2578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190610880565b506108ce9291506108d2565b5090565b6106af91905b808211156108ce57805473ffffffffffffffffffffffffffffffffffffffff191681556001016108d85600a165627a7a72305820b64a6b48b8cf5ba778e8633b37621b5c5635bf66a15ba6263d89da684b3105a20029

Verified Source Code Partial Match

Compiler: v0.4.24+commit.e67f0147 EVM: byzantium Optimization: Yes (200 runs)
SimpleMultiSig.sol 97 lines
pragma solidity ^0.4.24;

contract SimpleMultiSig {

// EIP712 Precomputed hashes:
// keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)")
bytes32 constant EIP712DOMAINTYPE_HASH = 0xd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472;

// keccak256("Simple MultiSig")
bytes32 constant NAME_HASH = 0xb7a0bfa1b79f2443f4d73ebb9259cddbcd510b18be6fc4da7d1aa7b1786e73e6;

// keccak256("1")
bytes32 constant VERSION_HASH = 0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;

// keccak256("MultiSigTransaction(address destination,uint256 value,bytes data,uint256 nonce,address executor,uint256 gasLimit)")
bytes32 constant TXTYPE_HASH = 0x3ee892349ae4bbe61dce18f95115b5dc02daf49204cc602458cd4c1f540d56d7;

bytes32 constant SALT = 0x251543af6a222378665a76fe38dbceae4871a070b7fdaf5c6c30cf758dc33cc0;

  uint public nonce;                 // (only) mutable state
  uint public threshold;             // immutable state
  mapping (address => bool) isOwner; // immutable state
  address[] public ownersArr;        // immutable state

  bytes32 DOMAIN_SEPARATOR;          // hash for EIP712, computed from contract address

  function owners() public view returns (address[]) {
    return ownersArr;
  }

  // Note that owners_ must be strictly increasing, in order to prevent duplicates
  function setOwners_(uint threshold_, address[] owners_) private {
    require(owners_.length <= 20 && threshold_ <= owners_.length && threshold_ > 0);

    // remove old owners from map
    for (uint i = 0; i < ownersArr.length; i++) {
      isOwner[ownersArr[i]] = false;
    }

    // add new owners to map
    address lastAdd = address(0);
    for (i = 0; i < owners_.length; i++) {
      require(owners_[i] > lastAdd);
      isOwner[owners_[i]] = true;
      lastAdd = owners_[i];
    }

    // set owners array and threshold
    ownersArr = owners_;
    threshold = threshold_;
  }

  constructor(uint threshold_, address[] owners_, uint chainId) public {
    setOwners_(threshold_, owners_);

    DOMAIN_SEPARATOR = keccak256(abi.encode(EIP712DOMAINTYPE_HASH,
                                            NAME_HASH,
                                            VERSION_HASH,
                                            chainId,
                                            this,
                                            SALT));
  }

  // Requires a quorum of owners to call from this contract using execute
  function setOwners(uint threshold_, address[] owners_) external {
    require(msg.sender == address(this));
    setOwners_(threshold_, owners_);
  }

  // Note that address recovered from signatures must be strictly increasing, in order to prevent duplicates
  function execute(uint8[] sigV, bytes32[] sigR, bytes32[] sigS, address destination, uint value, bytes data, address executor, uint gasLimit) public {
    require(sigR.length == threshold);
    require(sigR.length == sigS.length && sigR.length == sigV.length);
    require(executor == msg.sender || executor == address(0));

    // EIP712 scheme: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md
    bytes32 txInputHash = keccak256(abi.encode(TXTYPE_HASH, destination, value, keccak256(data), nonce, executor, gasLimit));
    bytes32 totalHash = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, txInputHash));

    address lastAdd = address(0); // cannot have address(0) as an owner
    for (uint i = 0; i < threshold; i++) {
      address recovered = ecrecover(totalHash, sigV[i], sigR[i], sigS[i]);
      require(recovered > lastAdd && isOwner[recovered]);
      lastAdd = recovered;
    }

    // If we make it here all signatures are accounted for.
    // The address.call() syntax is no longer recommended, see:
    // https://github.com/ethereum/solidity/issues/2884
    nonce = nonce + 1;
    bool success = false;
    assembly { success := call(gasLimit, destination, value, add(data, 0x20), mload(data), 0, 0) }
    require(success);
  }

  function () payable external {}
}

Read Contract

nonce 0xaffed0e0 → uint256
owners 0xaffe39c1 → address[]
ownersArr 0xaa5df9e2 → address
threshold 0x42cde4e8 → uint256

Write Contract 2 functions

These functions modify contract state and require a wallet transaction to execute.

execute 0xa0ab9653
uint8[] sigV
bytes32[] sigR
bytes32[] sigS
address destination
uint256 value
bytes data
address executor
uint256 gasLimit
setOwners 0xf3182e85
uint256 threshold_
address[] owners_

Recent Transactions

No transactions found for this address