账户
0xe9...a2f6
0xe9...a2F6

0xe9...a2F6

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.1+commit.df193b15
语言
Solidity
合同源代码
文件 1 的 1:EthBridge.sol
pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */

 
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);



    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    
}

contract EthBnbBridge {
    address public phnxAddress;
    address public signer;

    uint256 public nonce;
    mapping(bytes32 => bool) public sigRepeated;

    //keccak("ETH_BRIDGE_HASH_ONE")
    bytes32 public constant HASH_ONE = 0x63c7f5cdb1d38bbec4fca06b08adbb3c338e225bf61b79696076f193b0a70f07;
    //keccak("ETH_BRIDGE_HASH_TWO")
    bytes32 public constant HASH_TWO = 0xc17d317ce8d3846b73214929c7cc4a2a2679e1c043b10e5612748890112fb726;
    //keccak("ETH_BRIDGE_HASH_THREE")
    bytes32 public constant HASH_THREE = 0x521953684645f878093bce1437e3c6d4d19a8a16cb0cb7379b2da2e14f5bb7cb;

    event TokenDeposited(address user, uint256 amount, uint256 nonce);
    event TokenWithdrawn(address user, uint256 amount, uint256 nonce);

    constructor(address _phnxAddress, address _signer) {
        require(_phnxAddress!=address(0) && _signer!=address(0),"EthBnbBridge: Signer and Token cannot be zero Address");
        phnxAddress = _phnxAddress;
        signer = _signer;
    }

    function changeSigner(address _signer) external{
        require(signer==msg.sender,"Changing Signer Forbidden");
        signer = _signer;
    }

    function depositToken(uint256 amount) external {
        require(amount!=0,"EthBnbBridge: Amount Cannot be Zero");
        address sender = msg.sender;
        IERC20(phnxAddress).transferFrom(sender, address(this), amount);
        emit TokenDeposited(sender, amount, nonce++);
    }

    function withdrawToken(
        address sender,
        uint256 amount,
        uint256 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        require(sender == msg.sender, "Invalid sender");
        require(amount!=0,"EthBnbBridge: Amount Cannot be Zero");
        bytes32 encodeData = keccak256(abi.encode(amount, sender, nonce));
        require(!sigRepeated[encodeData], "Alredy claimed");
        sigRepeated[encodeData] = true;
        _validateSignedData(encodeData, v, r, s);
        IERC20(phnxAddress).transfer(sender, amount);
        emit TokenWithdrawn(sender, amount, nonce);
    }

    function getDomainSeparator() internal view returns (bytes32) {
        return keccak256(abi.encode(HASH_ONE, HASH_TWO, HASH_THREE, "0x01", address(this)));
    }

    function _validateSignedData(
        bytes32 encodeData,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal view {
        bytes32 digest = keccak256(abi.encodePacked("\x19\x01", getDomainSeparator(), encodeData));
        address recoveredAddress = ecrecover(digest, v, r, s);
        // Explicitly disallow authorizations for address(0) as ecrecover returns address(0) on malformed messages
        require(recoveredAddress != address(0) && recoveredAddress == signer, "Invlid Signature");
    }

    function withdrawTokens() external {
        require(msg.sender == signer);
        IERC20(phnxAddress).transfer(signer,IERC20(phnxAddress).balanceOf(address(this)));
    }
}
设置
{
  "compilationTarget": {
    "EthBridge.sol": "EthBnbBridge"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"_phnxAddress","type":"address"},{"internalType":"address","name":"_signer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"TokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"TokenWithdrawn","type":"event"},{"inputs":[],"name":"HASH_ONE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HASH_THREE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HASH_TWO","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"changeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phnxAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"sigRepeated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]