ETH Price: $1,981.31 (-1.93%)

Transaction Decoder

Block:
12729936 at Jun-29-2021 04:08:16 PM +UTC
Transaction Fee:
0.006052475 ETH $11.99
Gas Used:
242,099 Gas / 25 Gwei

Emitted Events:

194 0xc2e5d9937f81d87dbf07ce5af1ade6e215412f01.0xf2655ca50c134f2081360f02a1bf4714b79d312ffc82f90953fbb323f76d2e16( 0xf2655ca50c134f2081360f02a1bf4714b79d312ffc82f90953fbb323f76d2e16, 0x000000000000000000000000119b49a1c266c67656d098c320b697cc5ce94c43 )
195 InstaIndex.LogAccountCreated( sender=[Sender] 0x119b49a1c266c67656d098c320b697cc5ce94c43, owner=[Sender] 0x119b49a1c266c67656d098c320b697cc5ce94c43, account=0xc2e5d9937f81d87dbf07ce5af1ade6e215412f01, origin=0x00000000...000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x119b49A1...C5Ce94C43
3.846415505697726658 Eth
Nonce: 533
3.840363030697726658 Eth
Nonce: 534
0.006052475
0x2971AdFa...A9c74f723
(InstaDApp: Index)
0x4c8a1BEb...55194AbEb
(InstaDApp: List)
(Spark Pool)
16.027494165587012282 Eth16.033546640587012282 Eth0.006052475
0xC2E5D993...215412F01
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 497590261154554171967158006304237969909362695157026712734309706318788704461906183804738776776659057126497267

Execution Trace

InstaIndex.build( _owner=0x119b49A1C266c67656d098c320b697cC5Ce94C43, accountVersion=2, _origin=0x0000000000000000000000000000000000000000 ) => ( _account=0xC2E5D9937F81d87DBf07cE5af1adE6e215412F01 )
  • 0xc2e5d9937f81d87dbf07ce5af1ade6e215412f01.3d602d80( )
  • InstaList.init( _account=0xC2E5D9937F81d87DBf07cE5af1adE6e215412F01 )
  • 0xc2e5d9937f81d87dbf07ce5af1ade6e215412f01.5bfa1b68( )
    • InstaAccountV2.5bfa1b68( )
      • InstaImplementations.getImplementation( _sig=System.Byte[] ) => ( 0x28aDcDC02Ca7B3EDf11924102726066AA0fA7010 )
      • InstaDefaultImplementation.enable( user=0x119b49A1C266c67656d098c320b697cC5Ce94C43 )
        • InstaIndex.STATICCALL( )
        • InstaList.addAuth( _owner=0x119b49A1C266c67656d098c320b697cC5Ce94C43 )
          • 0xc2e5d9937f81d87dbf07ce5af1ade6e215412f01.2520e7ff( )
            • InstaAccountV2.2520e7ff( )
              File 1 of 5: InstaIndex
              pragma solidity ^0.6.0;
              pragma experimental ABIEncoderV2;
              
              /**
               * @title InstaIndex
               * @dev Main Contract For DeFi Smart Accounts. This is also a factory contract, Which deploys new Smart Account.
               * Also Registry for DeFi Smart Accounts.
               */
              
              interface AccountInterface {
                  function version() external view returns (uint);
                  function enable(address authority) external;
                  function cast(address[] calldata _targets, bytes[] calldata _datas, address _origin) external payable returns (bytes32[] memory responses);
              }
              
              interface ListInterface {
                  function init(address _account) external;
              }
              
              contract AddressIndex {
              
                  event LogNewMaster(address indexed master);
                  event LogUpdateMaster(address indexed master);
                  event LogNewCheck(uint indexed accountVersion, address indexed check);
                  event LogNewAccount(address indexed _newAccount, address indexed _connectors, address indexed _check);
              
                  // New Master Address.
                  address private newMaster;
                  // Master Address.
                  address public master;
                  // List Registry Address.
                  address public list;
              
                  // Connectors Modules(Account Module Version => Connectors Registry Module Address).
                  mapping (uint => address) public connectors;
                  // Check Modules(Account Module Version => Check Module Address).
                  mapping (uint => address) public check;
                  // Account Modules(Account Module Version => Account Module Address).
                  mapping (uint => address) public account;
                  // Version Count of Account Modules.
                  uint public versionCount;
              
                  /**
                  * @dev Throws if the sender not is Master Address.
                  */
                  modifier isMaster() {
                      require(msg.sender == master, "not-master");
                      _;
                  }
              
                  /**
                   * @dev Change the Master Address.
                   * @param _newMaster New Master Address.
                   */
                  function changeMaster(address _newMaster) external isMaster {
                      require(_newMaster != master, "already-a-master");
                      require(_newMaster != address(0), "not-valid-address");
                      require(newMaster != _newMaster, "already-a-new-master");
                      newMaster = _newMaster;
                      emit LogNewMaster(_newMaster);
                  }
              
                  function updateMaster() external {
                      require(newMaster != address(0), "not-valid-address");
                      require(msg.sender == newMaster, "not-master");
                      master = newMaster;
                      newMaster = address(0);
                      emit LogUpdateMaster(master);
                  }
              
                  /**
                   * @dev Change the Check Address of a specific Account Module version.
                   * @param accountVersion Account Module version.
                   * @param _newCheck The New Check Address.
                   */
                  function changeCheck(uint accountVersion, address _newCheck) external isMaster {
                      require(_newCheck != check[accountVersion], "already-a-check");
                      check[accountVersion] = _newCheck;
                      emit LogNewCheck(accountVersion, _newCheck);
                  }
              
                  /**
                   * @dev Add New Account Module.
                   * @param _newAccount The New Account Module Address.
                   * @param _connectors Connectors Registry Module Address.
                   * @param _check Check Module Address.
                   */
                  function addNewAccount(address _newAccount, address _connectors, address _check) external isMaster {
                      require(_newAccount != address(0), "not-valid-address");
                      versionCount++;
                      require(AccountInterface(_newAccount).version() == versionCount, "not-valid-version");
                      account[versionCount] = _newAccount;
                      if (_connectors != address(0)) connectors[versionCount] = _connectors;
                      if (_check != address(0)) check[versionCount] = _check;
                      emit LogNewAccount(_newAccount, _connectors, _check);
                  }
              
              }
              
              contract CloneFactory is AddressIndex {
                  /**
                   * @dev Clone a new Account Module.
                   * @param version Account Module version to clone.
                   */
                  function createClone(uint version) internal returns (address result) {
                      bytes20 targetBytes = bytes20(account[version]);
                      // solium-disable-next-line security/no-inline-assembly
                      assembly {
                          let clone := mload(0x40)
                          mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
                          mstore(add(clone, 0x14), targetBytes)
                          mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
                          result := create(0, clone, 0x37)
                      }
                  }
              
                  /**
                   * @dev Check if Account Module is a clone.
                   * @param version Account Module version.
                   * @param query Account Module Address.
                   */
                  function isClone(uint version, address query) external view returns (bool result) {
                      bytes20 targetBytes = bytes20(account[version]);
                      // solium-disable-next-line security/no-inline-assembly
                      assembly {
                          let clone := mload(0x40)
                          mstore(clone, 0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000)
                          mstore(add(clone, 0xa), targetBytes)
                          mstore(add(clone, 0x1e), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
              
                          let other := add(clone, 0x40)
                          extcodecopy(query, other, 0, 0x2d)
                          result := and(
                              eq(mload(clone), mload(other)),
                              eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
                          )
                      }
                  }
              }
              
              contract InstaIndex is CloneFactory {
              
                  event LogAccountCreated(address sender, address indexed owner, address indexed account, address indexed origin);
              
                  /**
                   * @dev Create a new DeFi Smart Account for a user and run cast function in the new Smart Account.
                   * @param _owner Owner of the Smart Account.
                   * @param accountVersion Account Module version.
                   * @param _targets Array of Target to run cast function.
                   * @param _datas Array of Data(callData) to run cast function.
                   * @param _origin Where Smart Account is created.
                   */
                  function buildWithCast(
                      address _owner,
                      uint accountVersion,
                      address[] calldata _targets,
                      bytes[] calldata _datas,
                      address _origin
                  ) external payable returns (address _account) {
                      _account = build(_owner, accountVersion, _origin);
                      if (_targets.length > 0) AccountInterface(_account).cast.value(msg.value)(_targets, _datas, _origin);
                  }
              
                  /**
                   * @dev Create a new DeFi Smart Account for a user.
                   * @param _owner Owner of the Smart Account.
                   * @param accountVersion Account Module version.
                   * @param _origin Where Smart Account is created.
                   */
                  function build(
                      address _owner,
                      uint accountVersion,
                      address _origin
                  ) public returns (address _account) {
                      require(accountVersion != 0 && accountVersion <= versionCount, "not-valid-account");
                      _account = createClone(accountVersion);
                      ListInterface(list).init(_account);
                      AccountInterface(_account).enable(_owner);
                      emit LogAccountCreated(msg.sender, _owner, _account, _origin);
                  }
              
                  /**
                   * @dev Setup Initial things for InstaIndex, after its been deployed and can be only run once.
                   * @param _master The Master Address.
                   * @param _list The List Address.
                   * @param _account The Account Module Address.
                   * @param _connectors The Connectors Registry Module Address.
                   */
                  function setBasics(
                      address _master,
                      address _list,
                      address _account,
                      address _connectors
                  ) external {
                      require(
                          master == address(0) &&
                          list == address(0) &&
                          account[1] == address(0) &&
                          connectors[1] == address(0) &&
                          versionCount == 0,
                          "already-defined"
                      );
                      master = _master;
                      list = _list;
                      versionCount++;
                      account[versionCount] = _account;
                      connectors[versionCount] = _connectors;
                  }
              
              }

              File 2 of 5: InstaList
              pragma solidity ^0.6.0;
              
              /**
               * @title InstaList
               * @dev Registry For DeFi Smart Account Authorised user.
               */
              
              interface AccountInterface {
                  function isAuth(address _user) external view returns (bool);
              }
              
              
              contract DSMath {
              
                  function add(uint64 x, uint64 y) internal pure returns (uint64 z) {
                      require((z = x + y) >= x, "ds-math-add-overflow");
                  }
              
                  function sub(uint64 x, uint64 y) internal pure returns (uint64 z) {
                      require((z = x - y) <= x, "ds-math-sub-underflow");
                  }
              
              }
              
              
              contract Variables is DSMath {
              
                  // InstaIndex Address.
                  address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723;
              
                  // Smart Account Count.
                  uint64 public accounts;
                  // Smart Account ID (Smart Account Address => Account ID).
                  mapping (address => uint64) public accountID;
                  // Smart Account Address (Smart Account ID => Smart Account Address).
                  mapping (uint64 => address) public accountAddr;
              
                  // User Link (User Address => UserLink(Account ID of First and Last And Count of Smart Accounts)).
                  mapping (address => UserLink) public userLink;
                  // Linked List of Users (User Address => Smart Account ID => UserList(Previous and next Account ID)).
                  mapping (address => mapping(uint64 => UserList)) public userList;
              
                  struct UserLink {
                      uint64 first;
                      uint64 last;
                      uint64 count;
                  }
                  struct UserList {
                      uint64 prev;
                      uint64 next;
                  }
              
                  // Account Link (Smart Account ID => AccountLink).
                  mapping (uint64 => AccountLink) public accountLink; // account => account linked list connection
                  // Linked List of Accounts (Smart Account ID => Account Address => AccountList).
                  mapping (uint64 => mapping (address => AccountList)) public accountList; // account => user address => list
              
                  struct AccountLink {
                      address first;
                      address last;
                      uint64 count;
                  }
                  struct AccountList {
                      address prev;
                      address next;
                  }
              
              }
              
              contract Configure is Variables {
              
                  /**
                   * @dev Add Account to User Linked List.
                   * @param _owner Account Owner.
                   * @param _account Smart Account Address.
                  */
                  function addAccount(address _owner, uint64 _account) internal {
                      if (userLink[_owner].last != 0) {
                          userList[_owner][_account].prev = userLink[_owner].last;
                          userList[_owner][userLink[_owner].last].next = _account;
                      }
                      if (userLink[_owner].first == 0) userLink[_owner].first = _account;
                      userLink[_owner].last = _account;
                      userLink[_owner].count = add(userLink[_owner].count, 1);
                  }
              
                  /**
                   * @dev Remove Account from User Linked List.
                   * @param _owner Account Owner/User.
                   * @param _account Smart Account Address.
                  */
                  function removeAccount(address _owner, uint64 _account) internal {
                      uint64 _prev = userList[_owner][_account].prev;
                      uint64 _next = userList[_owner][_account].next;
                      if (_prev != 0) userList[_owner][_prev].next = _next;
                      if (_next != 0) userList[_owner][_next].prev = _prev;
                      if (_prev == 0) userLink[_owner].first = _next;
                      if (_next == 0) userLink[_owner].last = _prev;
                      userLink[_owner].count = sub(userLink[_owner].count, 1);
                      delete userList[_owner][_account];
                  }
              
                  /**
                   * @dev Add Owner to Account Linked List.
                   * @param _owner Account Owner.
                   * @param _account Smart Account Address.
                  */
                  function addUser(address _owner, uint64 _account) internal {
                      if (accountLink[_account].last != address(0)) {
                          accountList[_account][_owner].prev = accountLink[_account].last;
                          accountList[_account][accountLink[_account].last].next = _owner;
                      }
                      if (accountLink[_account].first == address(0)) accountLink[_account].first = _owner;
                      accountLink[_account].last = _owner;
                      accountLink[_account].count = add(accountLink[_account].count, 1);
                  }
              
                  /**
                   * @dev Remove Owner from Account Linked List.
                   * @param _owner Account Owner.
                   * @param _account Smart Account Address.
                  */
                  function removeUser(address _owner, uint64 _account) internal {
                      address _prev = accountList[_account][_owner].prev;
                      address _next = accountList[_account][_owner].next;
                      if (_prev != address(0)) accountList[_account][_prev].next = _next;
                      if (_next != address(0)) accountList[_account][_next].prev = _prev;
                      if (_prev == address(0)) accountLink[_account].first = _next;
                      if (_next == address(0)) accountLink[_account].last = _prev;
                      accountLink[_account].count = sub(accountLink[_account].count, 1);
                      delete accountList[_account][_owner];
                  }
              
              }
              
              contract InstaList is Configure {
              
                  /**
                   * @dev Enable Auth for Smart Account.
                   * @param _owner Owner Address.
                  */
                  function addAuth(address _owner) external {
                      require(accountID[msg.sender] != 0, "not-account");
                      require(AccountInterface(msg.sender).isAuth(_owner), "not-owner");
                      addAccount(_owner, accountID[msg.sender]);
                      addUser(_owner, accountID[msg.sender]);
                  }
              
                  /**
                   * @dev Disable Auth for Smart Account.
                   * @param _owner Owner Address.
                  */
                  function removeAuth(address _owner) external {
                      require(accountID[msg.sender] != 0, "not-account");
                      require(!AccountInterface(msg.sender).isAuth(_owner), "already-owner");
                      removeAccount(_owner, accountID[msg.sender]);
                      removeUser(_owner, accountID[msg.sender]);
                  }
              
                  /**
                   * @dev Setup Initial configuration of Smart Account.
                   * @param _account Smart Account Address.
                  */
                  function init(address  _account) external {
                      require(msg.sender == instaIndex, "not-index");
                      accounts++;
                      accountID[_account] = accounts;
                      accountAddr[accounts] = _account;
                  }
              
              }

              File 3 of 5: InstaAccountV2
              // SPDX-License-Identifier: MIT
              pragma solidity ^0.7.0;
              interface AccountImplementations {
                  function getImplementation(bytes4 _sig) external view returns (address);
              }
              /**
               * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
               * instruction `delegatecall`.
               */
              contract InstaAccountV2 {
                  AccountImplementations public immutable implementations;
                  constructor(address _implementations) {
                      implementations = AccountImplementations(_implementations);
                  }
                  /**
                   * @dev Delegates the current call to `implementation`.
                   * 
                   * This function does not return to its internall call site, it will return directly to the external caller.
                   */
                  function _delegate(address implementation) internal {
                      // solhint-disable-next-line no-inline-assembly
                      assembly {
                          // Copy msg.data. We take full control of memory in this inline assembly
                          // block because it will not return to Solidity code. We overwrite the
                          // Solidity scratch pad at memory position 0.
                          calldatacopy(0, 0, calldatasize())
                          // Call the implementation.
                          // out and outsize are 0 because we don't know the size yet.
                          let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
                          // Copy the returned data.
                          returndatacopy(0, 0, returndatasize())
                          switch result
                          // delegatecall returns 0 on error.
                          case 0 { revert(0, returndatasize()) }
                          default { return(0, returndatasize()) }
                      }
                  }
                  /**
                   * @dev Delegates the current call to the address returned by Implementations registry.
                   * 
                   * This function does not return to its internall call site, it will return directly to the external caller.
                   */
                  function _fallback(bytes4 _sig) internal {
                      address _implementation = implementations.getImplementation(_sig);
                      require(_implementation != address(0), "InstaAccountV2: Not able to find _implementation");
                      _delegate(_implementation);
                  }
                  /**
                   * @dev Fallback function that delegates calls to the address returned by Implementations registry.
                   */
                  fallback () external payable {
                      _fallback(msg.sig);
                  }
                  /**
                   * @dev Fallback function that delegates calls to the address returned by Implementations registry.
                   */
                  receive () external payable {
                      if (msg.sig != 0x00000000) {
                          _fallback(msg.sig);
                      }
                  }
              }
              

              File 4 of 5: InstaImplementations
              // SPDX-License-Identifier: MIT
              pragma solidity ^0.7.0;
              interface IndexInterface {
                  function master() external view returns (address);
              }
              contract Setup {
                  address public defaultImplementation;
                  mapping (bytes4 => address) internal sigImplementations;
                  mapping (address => bytes4[]) internal implementationSigs;
              }
              contract Implementations is Setup {
                  event LogSetDefaultImplementation(address indexed oldImplementation, address indexed newImplementation);
                  event LogAddImplementation(address indexed implementation, bytes4[] sigs);
                  event LogRemoveImplementation(address indexed implementation, bytes4[] sigs);
                  IndexInterface constant public instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
                  modifier isMaster() {
                      require(msg.sender == instaIndex.master(), "Implementations: not-master");
                      _;
                  }
                  function setDefaultImplementation(address _defaultImplementation) external isMaster {
                      require(_defaultImplementation != address(0), "Implementations: _defaultImplementation address not valid");
                      require(_defaultImplementation != defaultImplementation, "Implementations: _defaultImplementation cannot be same");
                      emit LogSetDefaultImplementation(defaultImplementation, _defaultImplementation);
                      defaultImplementation = _defaultImplementation;
                  }
                  function addImplementation(address _implementation, bytes4[] calldata _sigs) external isMaster {
                      require(_implementation != address(0), "Implementations: _implementation not valid.");
                      require(implementationSigs[_implementation].length == 0, "Implementations: _implementation already added.");
                      for (uint i = 0; i < _sigs.length; i++) {
                          bytes4 _sig = _sigs[i];
                          require(sigImplementations[_sig] == address(0), "Implementations: _sig already added");
                          sigImplementations[_sig] = _implementation;
                      }
                      implementationSigs[_implementation] = _sigs;
                      emit LogAddImplementation(_implementation, _sigs);
                  }
                  function removeImplementation(address _implementation) external isMaster {
                      require(_implementation != address(0), "Implementations: _implementation not valid.");
                      require(implementationSigs[_implementation].length != 0, "Implementations: _implementation not found.");
                      bytes4[] memory sigs = implementationSigs[_implementation];
                      for (uint i = 0; i < sigs.length; i++) {
                          bytes4 sig = sigs[i];
                          delete sigImplementations[sig];
                      }
                      delete implementationSigs[_implementation];
                      emit LogRemoveImplementation(_implementation, sigs);
                  }
              }
              contract InstaImplementations is Implementations {
                  function getImplementation(bytes4 _sig) external view returns (address) {
                      address _implementation = sigImplementations[_sig];
                      return _implementation == address(0) ? defaultImplementation : _implementation;
                  }
                  function getImplementationSigs(address _impl) external view returns (bytes4[] memory) {
                      return implementationSigs[_impl];
                  }
                  function getSigImplementation(bytes4 _sig) external view returns (address) {
                      return sigImplementations[_sig];
                  }
              }
              

              File 5 of 5: InstaDefaultImplementation
              pragma solidity ^0.7.0;
              pragma experimental ABIEncoderV2;
              import { Variables } from "./variables.sol";
              interface IndexInterface {
                  function list() external view returns (address);
              }
              interface ListInterface {
                  function addAuth(address user) external;
                  function removeAuth(address user) external;
              }
              contract Constants is Variables {
                  uint public constant implementationVersion = 1;
                  // InstaIndex Address.
                  address public constant instaIndex = 0x2971AdFa57b20E5a416aE5a708A8655A9c74f723;
                  // The Account Module Version.
                  uint public constant version = 2;
              }
              contract Record is Constants {
                  event LogEnableUser(address indexed user);
                  event LogDisableUser(address indexed user);
                  /**
                   * @dev Check for Auth if enabled.
                   * @param user address/user/owner.
                   */
                  function isAuth(address user) public view returns (bool) {
                      return _auth[user];
                  }
                  /**
                   * @dev Enable New User.
                   * @param user Owner address
                  */
                  function enable(address user) public {
                      require(msg.sender == address(this) || msg.sender == instaIndex, "not-self-index");
                      require(user != address(0), "not-valid");
                      require(!_auth[user], "already-enabled");
                      _auth[user] = true;
                      ListInterface(IndexInterface(instaIndex).list()).addAuth(user);
                      emit LogEnableUser(user);
                  }
                  /**
                   * @dev Disable User.
                   * @param user Owner address
                  */
                  function disable(address user) public {
                      require(msg.sender == address(this), "not-self");
                      require(user != address(0), "not-valid");
                      require(_auth[user], "already-disabled");
                      delete _auth[user];
                      ListInterface(IndexInterface(instaIndex).list()).removeAuth(user);
                      emit LogDisableUser(user);
                  }
              }
              contract InstaDefaultImplementation is Record {
                  receive() external payable {}
              }pragma solidity ^0.7.0;
              contract Variables {
                  // Auth Module(Address of Auth => bool).
                  mapping (address => bool) internal _auth;
              }