ETH Price: $1,947.34 (-1.18%)

Contract

0x7390251Bf35AA7eA7C196fc4750bd5d6c5918329
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DirectExitAdministrator

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

import {ITokenDeposit} from "./interfaces/ITokenDeposit.sol";
import {ITokenPairs} from "./interfaces/ITokenPairs.sol";
import {IProofVerifier} from "./interfaces/IProofVerifier.sol";

/// DirectExitAdministrator allows to withdraw direct ERC-20 balance from L2 if the bridge becomes dead.
/// Withdrawn ERC-20 tokens needs to be owned by the calling user.
/// @custom:security-contact [email protected]
contract DirectExitAdministrator {
    ITokenDeposit public immutable deposit;
    mapping (bytes32 senderToken => bool isWithdrawn) public tokenWithdrawn; // already withdrawn tokens

    constructor(address _deposit) {
        require(_deposit != address(0), "TokenDeposit address not set");
        deposit = ITokenDeposit(_deposit);
    }

    /// Withdraw ERC-20 balance from L2. Can be used only if the bridge died.
    function withdraw(address token, uint256 amount, bytes calldata proof) public {
        require(deposit.fetchDeadStatus(), "Bridge is not dead");
        bytes32 withdrawHash = keccak256(abi.encode(msg.sender, token));
        require(tokenWithdrawn[withdrawHash] == false, "Already withdrawn");

        address mintedToken = ITokenPairs(deposit.tokenPairs()).originalToMinted(token);
        require(mintedToken != address(0), "No minted token for given token");

        IProofVerifier(deposit.proofVerifier()).verifyProof(
            mintedToken,
            getBalanceSlotIndex(msg.sender),
            bytes32(amount),
            deposit.deadState(),
            proof
        );
        // user has given balance of the minted token

        tokenWithdrawn[withdrawHash] = true; // write before other contract call (reentrancy!)
        deposit.withdrawWhileDead(msg.sender, token, amount);
    }

    // storage slot of balances mapping used by OpenZeppelin ERC20Upgradeable
    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;

    /// Calculate slotId for minted ERC-20 balance.
    function getBalanceSlotIndex(address account) pure public returns (bytes32) {
        return keccak256(abi.encode(account, ERC20StorageLocation)); // balance expected at slot used by ERC20Upgradeable
    }

}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

/// Proof verifier allows to validate witness proof about a storage slot value on a different chain.
interface IProofVerifier {

    /// Verify witness proof - proof about storage slot value on a different chain.
    /// Reverts if the slot value does not match the expected value or if the proof is invalid.
    function verifyProof(address contractAddress, bytes32 slotIndex, bytes32 expectedValue, bytes32 stateRoot, bytes calldata proof) external view;

}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

/// Interface of a token deposit manageable (in case of the bridge death) by ExitAdministrator.
interface ITokenDeposit {
    function withdrawWhileDead(address recipient, address token, uint256 amount) external;
    function fetchDeadStatus() external returns (bool);
    function deadState() external view returns (bytes32);
    function proofVerifier() external view returns (address);
    function tokenPairs() external view returns (address);
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

// The token pairs registry maps Ethereum ERC-20 tokens to L2 tokens minted by the bridge.
interface ITokenPairs {
    /// Map Ethereum token to L2 token - pairs can be only added into this mapping.
    function originalToMinted(address) external view returns (address);

    /// Map Ethereum token to L2 token - pairs can be removed from here to block new transfers.
    function originalToMintedTerminable(address) external view returns (address);

    /// Map L2 token to Ethereum token - pairs can be only added into this mapping.
    function mintedToOriginal(address) external view returns (address);

    /// Check if the account has given role - allows to use TokenPairs as an AccessManager for USDC burning ops.
    function hasRole(bytes32 role, address account) external view returns (bool);
}

Settings
{
  "evmVersion": "cancun",
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_deposit","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"deposit","outputs":[{"internalType":"contract ITokenDeposit","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getBalanceSlotIndex","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"senderToken","type":"bytes32"}],"name":"tokenWithdrawn","outputs":[{"internalType":"bool","name":"isWithdrawn","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405234801561000f575f5ffd5b5060405161089938038061089983398101604081905261002e91610099565b6001600160a01b0381166100885760405162461bcd60e51b815260206004820152601c60248201527f546f6b656e4465706f7369742061646472657373206e6f742073657400000000604482015260640160405180910390fd5b6001600160a01b03166080526100c6565b5f602082840312156100a9575f5ffd5b81516001600160a01b03811681146100bf575f5ffd5b9392505050565b60805161079a6100ff5f395f818160c00152818160fc015281816102490152818161038a015281816104250152610535015261079a5ff3fe608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806331f092651461004e5780634a04f559146100635780636ac72d7a1461009a578063d0e30db0146100bb575b5f5ffd5b61006161005c366004610603565b6100fa565b005b610085610071366004610688565b5f6020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100ad6100a836600461069f565b610595565b604051908152602001610091565b6100e27f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610091565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638affb8226040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610157573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061017b91906106c1565b6101c15760405162461bcd60e51b8152602060048201526012602482015271109c9a5919d9481a5cc81b9bdd081919585960721b60448201526064015b60405180910390fd5b60408051336020808301919091526001600160a01b03871682840152825180830384018152606090920183528151918101919091205f818152918290529190205460ff16156102465760405162461bcd60e51b815260206004820152601160248201527020b63932b0b23c903bb4ba34323930bbb760791b60448201526064016101b8565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031662d460146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102c691906106e0565b60405163fe2f9dd760e01b81526001600160a01b038881166004830152919091169063fe2f9dd790602401602060405180830381865afa15801561030c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061033091906106e0565b90506001600160a01b0381166103885760405162461bcd60e51b815260206004820152601f60248201527f4e6f206d696e74656420746f6b656e20666f7220676976656e20746f6b656e0060448201526064016101b8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316637fa417b36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e4573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040891906106e0565b6001600160a01b0316636a5310d08261042033610595565b885f1b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663baac0df06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561047f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a391906106fb565b89896040518763ffffffff1660e01b81526004016104c696959493929190610712565b5f6040518083038186803b1580156104dc575f5ffd5b505afa1580156104ee573d5f5f3e3d5ffd5b5050505f8381526020819052604090819020805460ff191660011790555163060c1ded60e51b81523360048201526001600160a01b038881166024830152604482018890527f000000000000000000000000000000000000000000000000000000000000000016915063c183bda0906064015f604051808303815f87803b158015610577575f5ffd5b505af1158015610589573d5f5f3e3d5ffd5b50505050505050505050565b604080516001600160a01b03929092166020808401919091527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00838301528151808403830181526060909301909152815191012090565b6001600160a01b0381168114610600575f5ffd5b50565b5f5f5f5f60608587031215610616575f5ffd5b8435610621816105ec565b935060208501359250604085013567ffffffffffffffff811115610643575f5ffd5b8501601f81018713610653575f5ffd5b803567ffffffffffffffff811115610669575f5ffd5b87602082840101111561067a575f5ffd5b949793965060200194505050565b5f60208284031215610698575f5ffd5b5035919050565b5f602082840312156106af575f5ffd5b81356106ba816105ec565b9392505050565b5f602082840312156106d1575f5ffd5b815180151581146106ba575f5ffd5b5f602082840312156106f0575f5ffd5b81516106ba816105ec565b5f6020828403121561070b575f5ffd5b5051919050565b60018060a01b038716815285602082015284604082015283606082015260a060808201528160a0820152818360c08301375f81830160c090810191909152601f909201601f191601019594505050505056fea2646970667358221220a0e9fec5c86a8b07799afc50ffa1a45cfa1061624b9932c30e9fc9a299d01e8e64736f6c634300081b0033000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec20

Deployed Bytecode

0x608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806331f092651461004e5780634a04f559146100635780636ac72d7a1461009a578063d0e30db0146100bb575b5f5ffd5b61006161005c366004610603565b6100fa565b005b610085610071366004610688565b5f6020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100ad6100a836600461069f565b610595565b604051908152602001610091565b6100e27f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec2081565b6040516001600160a01b039091168152602001610091565b7f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec206001600160a01b0316638affb8226040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610157573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061017b91906106c1565b6101c15760405162461bcd60e51b8152602060048201526012602482015271109c9a5919d9481a5cc81b9bdd081919585960721b60448201526064015b60405180910390fd5b60408051336020808301919091526001600160a01b03871682840152825180830384018152606090920183528151918101919091205f818152918290529190205460ff16156102465760405162461bcd60e51b815260206004820152601160248201527020b63932b0b23c903bb4ba34323930bbb760791b60448201526064016101b8565b5f7f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec206001600160a01b031662d460146040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102a2573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102c691906106e0565b60405163fe2f9dd760e01b81526001600160a01b038881166004830152919091169063fe2f9dd790602401602060405180830381865afa15801561030c573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061033091906106e0565b90506001600160a01b0381166103885760405162461bcd60e51b815260206004820152601f60248201527f4e6f206d696e74656420746f6b656e20666f7220676976656e20746f6b656e0060448201526064016101b8565b7f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec206001600160a01b0316637fa417b36040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e4573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061040891906106e0565b6001600160a01b0316636a5310d08261042033610595565b885f1b7f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec206001600160a01b031663baac0df06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561047f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a391906106fb565b89896040518763ffffffff1660e01b81526004016104c696959493929190610712565b5f6040518083038186803b1580156104dc575f5ffd5b505afa1580156104ee573d5f5f3e3d5ffd5b5050505f8381526020819052604090819020805460ff191660011790555163060c1ded60e51b81523360048201526001600160a01b038881166024830152604482018890527f000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec2016915063c183bda0906064015f604051808303815f87803b158015610577575f5ffd5b505af1158015610589573d5f5f3e3d5ffd5b50505050505050505050565b604080516001600160a01b03929092166020808401919091527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00838301528151808403830181526060909301909152815191012090565b6001600160a01b0381168114610600575f5ffd5b50565b5f5f5f5f60608587031215610616575f5ffd5b8435610621816105ec565b935060208501359250604085013567ffffffffffffffff811115610643575f5ffd5b8501601f81018713610653575f5ffd5b803567ffffffffffffffff811115610669575f5ffd5b87602082840101111561067a575f5ffd5b949793965060200194505050565b5f60208284031215610698575f5ffd5b5035919050565b5f602082840312156106af575f5ffd5b81356106ba816105ec565b9392505050565b5f602082840312156106d1575f5ffd5b815180151581146106ba575f5ffd5b5f602082840312156106f0575f5ffd5b81516106ba816105ec565b5f6020828403121561070b575f5ffd5b5051919050565b60018060a01b038716815285602082015284604082015283606082015260a060808201528160a0820152818360c08301375f81830160c090810191909152601f909201601f191601019594505050505056fea2646970667358221220a0e9fec5c86a8b07799afc50ffa1a45cfa1061624b9932c30e9fc9a299d01e8e64736f6c634300081b0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec20

-----Decoded View---------------
Arg [0] : _deposit (address): 0xa1E2481a9CD0Cb0447EeB1cbc26F1b3fff3bec20

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a1e2481a9cd0cb0447eeb1cbc26f1b3fff3bec20


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.