Source Code
Overview
ETH Balance
70,979.248348336448096413 ETH
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Lock | 7822710 | 19 days ago | 0.05 ETH | ||||
Lock | 7822683 | 19 days ago | 0.15 ETH | ||||
Lock | 7822683 | 19 days ago | 0.15 ETH | ||||
Lock | 7820727 | 19 days ago | 0.05 ETH | ||||
Lock | 7820685 | 19 days ago | 0.03 ETH | ||||
Lock | 7820608 | 19 days ago | 0.05 ETH | ||||
Lock | 7820571 | 19 days ago | 0.02 ETH | ||||
Lock | 7820536 | 19 days ago | 0.05 ETH | ||||
Lock | 7819631 | 19 days ago | 0.01 ETH | ||||
Lock | 7819582 | 19 days ago | 0.05 ETH | ||||
Lock | 7819569 | 19 days ago | 0.25 ETH | ||||
Lock | 7813839 | 20 days ago | 0.03 ETH | ||||
Lock | 7813812 | 20 days ago | 0.02 ETH | ||||
Lock | 7813728 | 20 days ago | 0.02 ETH | ||||
Lock | 7813721 | 20 days ago | 0.03 ETH | ||||
Lock | 7813711 | 20 days ago | 0.03 ETH | ||||
Lock | 7810449 | 21 days ago | 0.05 ETH | ||||
Lock | 7802081 | 22 days ago | 0.02 ETH | ||||
Lock | 7802076 | 22 days ago | 0.0547 ETH | ||||
Lock | 6657194 | 194 days ago | 0.04 ETH | ||||
Lock | 6655724 | 195 days ago | 0.04 ETH | ||||
Lock | 6654245 | 195 days ago | 0.04 ETH | ||||
Lock | 6652749 | 195 days ago | 0.04 ETH | ||||
Lock | 6651252 | 195 days ago | 0.04 ETH | ||||
Lock | 6649777 | 196 days ago | 0.04 ETH |
Loading...
Loading
Contract Name:
LockProxyV1
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "openzeppelin-contracts/contracts/access/Ownable.sol"; import "openzeppelin-contracts/contracts/security/Pausable.sol"; import "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; import "../core/interfaces/IBridgeProxy.sol"; import "../core/interfaces/IBridgeLogic.sol"; import "../libs/ZeroCopySink.sol"; import "../libs/ZeroCopySource.sol"; import "../libs/Utils.sol"; import "./interfaces/ILockProxy.sol"; // import "openzeppelin-contracts/contracts/security/ReentrancyGuard.sol"; contract LockProxyV1 is Ownable, Pausable, ILockProxy { using SafeERC20 for IERC20; struct TxArgs { bytes toAssetHash; bytes toAddress; uint256 amount; } address public bridgeProxy; mapping(address => mapping(uint64 => bytes)) public assetHashMap; mapping(uint64 => bytes) public proxyHashMap; event SetBridgeProxyEvent(address bridgeProxy); event LockEvent( address fromAssetHash, address fromAddress, uint64 toChainId, bytes toAssetHash, bytes toAddress, uint256 amount ); event UnlockEvent(address toAssetHash, address toAddress, uint256 amount); event BindProxyEvent(uint64 toChainId, bytes targetProxyHash); event BindAssetEvent( address fromAssetHash, uint64 toChainId, bytes targetProxyHash, uint initialAmount ); function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } modifier onlyBridgeProxy() { require(_msgSender() == bridgeProxy, "msg.sender is not bridgeProxy"); _; } function setBridgeProxy(address _bridgeProxy) public onlyOwner { bridgeProxy = _bridgeProxy; emit SetBridgeProxyEvent(_bridgeProxy); } function lock( address fromAssetHash, uint16 toChainId, bytes memory toAddress, uint256 amount ) public payable returns (bool) { require(amount != 0, "!amount"); require( _transferToContract(fromAssetHash, amount), "!_transferToContract" ); bytes memory toAssetHash = assetHashMap[fromAssetHash][toChainId]; require(toAssetHash.length != 0, "!toAssetHash"); TxArgs memory txArgs = TxArgs({ toAssetHash: toAssetHash, toAddress: toAddress, amount: amount }); bytes memory txData = _serializeTxArgs(txArgs); IBridgeLogic logic = IBridgeLogic(IBridgeProxy(bridgeProxy).logic()); bytes memory toProxyHash = proxyHashMap[toChainId]; require(toProxyHash.length != 0, "!toProxyHash"); logic.send(toChainId, toProxyHash, txData); emit LockEvent( fromAssetHash, _msgSender(), toChainId, toAssetHash, toAddress, amount ); return true; } function onReceive( uint16 /*_srcChainID*/, bytes calldata _srcAddress, uint256 /*_nonce*/, bytes calldata _payload ) external onlyBridgeProxy returns (bool) { require( _srcAddress.length != 0, "from proxy contract address cannot be empty" ); TxArgs memory args = _deserializeTxArgs(_payload); require(args.toAssetHash.length != 0, "toAssetHash cannot be empty"); address toAssetHash = Utils.bytesToAddress(args.toAssetHash); require(args.toAddress.length != 0, "toAddress cannot be empty"); address toAddress = Utils.bytesToAddress(args.toAddress); require( _transferFromContract(toAssetHash, toAddress, args.amount), "transfer asset from lock_proxy contract to toAddress failed!" ); emit UnlockEvent(toAssetHash, toAddress, args.amount); return true; } function bindProxyHash( uint64 toChainId, bytes memory targetProxyHash ) public onlyOwner returns (bool) { proxyHashMap[toChainId] = targetProxyHash; emit BindProxyEvent(toChainId, targetProxyHash); return true; } function bindAssetHash( address fromAssetHash, uint64 toChainId, bytes memory toAssetHash ) public onlyOwner returns (bool) { assetHashMap[fromAssetHash][toChainId] = toAssetHash; emit BindAssetEvent( fromAssetHash, toChainId, toAssetHash, getBalanceFor(fromAssetHash) ); return true; } function getBalanceFor( address fromAssetHash ) public view returns (uint256) { if (fromAssetHash == address(0)) { // return address(this).balance; // this expression would result in error: Failed to decode output: Error: insufficient data for uint256 type address selfAddr = address(this); return selfAddr.balance; } else { IERC20 erc20Token = IERC20(fromAssetHash); return erc20Token.balanceOf(address(this)); } } function _transferFromContract( address toAssetHash, address toAddress, uint256 amount ) internal returns (bool) { if ( toAssetHash == address(0x0000000000000000000000000000000000000000) ) { // toAssetHash === address(0) denotes contract needs to unlock ether to toAddress // convert toAddress from 'address' type to 'address payable' type, then actively transfer ether payable(address(uint160(toAddress))).transfer(amount); } else { // actively transfer amount of asset from lock_proxy contract to toAddress require( _transferERC20FromContract(toAssetHash, toAddress, amount), "transfer erc20 asset from lock_proxy contract to toAddress failed!" ); } return true; } function _transferToContract( address fromAssetHash, uint256 amount ) internal returns (bool) { if (fromAssetHash == address(0)) { // fromAssetHash === address(0) denotes user choose to lock ether // passively check if the received msg.value equals amount require(msg.value != 0, "transferred ether cannot be zero!"); require( msg.value == amount, "transferred ether is not equal to amount!" ); } else { // make sure lockproxy contract will decline any received ether require(msg.value == 0, "there should be no ether transfer!"); // actively transfer amount of asset from msg.sender to lock_proxy contract require( _transferERC20ToContract( fromAssetHash, _msgSender(), address(this), amount ), "transfer erc20 asset to lock_proxy contract failed!" ); } return true; } function _transferERC20FromContract( address toAssetHash, address toAddress, uint256 amount ) internal returns (bool) { IERC20 erc20Token = IERC20(toAssetHash); // require(erc20Token.transfer(toAddress, amount), "trasnfer ERC20 Token failed!"); erc20Token.safeTransfer(toAddress, amount); return true; } function _transferERC20ToContract( address fromAssetHash, address fromAddress, address toAddress, uint256 amount ) internal returns (bool) { IERC20 erc20Token = IERC20(fromAssetHash); // require(erc20Token.transferFrom(fromAddress, toAddress, amount), "trasnfer ERC20 Token failed!"); erc20Token.safeTransferFrom(fromAddress, toAddress, amount); return true; } function _serializeTxArgs( TxArgs memory args ) internal pure returns (bytes memory) { bytes memory buff; buff = abi.encodePacked( ZeroCopySink.WriteVarBytes(args.toAssetHash), ZeroCopySink.WriteVarBytes(args.toAddress), ZeroCopySink.WriteUint255(args.amount) ); return buff; } function _deserializeTxArgs( bytes memory valueBs ) internal pure returns (TxArgs memory) { TxArgs memory args; uint256 off = 0; (args.toAssetHash, off) = ZeroCopySource.NextVarBytes(valueBs, off); (args.toAddress, off) = ZeroCopySource.NextVarBytes(valueBs, off); (args.amount, off) = ZeroCopySource.NextUint255(valueBs, off); return args; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IBridgeLogic { function send( uint16 _dstChainID, bytes calldata _destination, bytes calldata _payload ) external; function receivePayload( uint16 _srcChainID, uint256 _nonce, bytes calldata _srcAddress, address _dstAddress, bytes calldata _payload, bytes calldata _sigs, uint256 _gasLimit ) external; function updateKeepers( address[] calldata _newKeepers, bytes calldata _sigs ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IBridgeProxy { function logic() external returns (address); function sendFromLogic( address sender, uint16 _dstChainID, bytes calldata _destination, bytes calldata _payload ) external; function receivePayloadFromLogic( uint16 _srcChainID, uint256 _nonce, bytes calldata _srcAddress, address _dstAddress, bytes calldata _payload, uint256 _gasLimit ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; library Utils { function bytesToBytes32( bytes memory _bs ) internal pure returns (bytes32 value) { require(_bs.length == 32, "bytes length is not 32."); assembly { // load 32 bytes from memory starting from position _bs + 0x20 since the first 0x20 bytes stores _bs length value := mload(add(_bs, 0x20)) } } function bytesToAddress( bytes memory _bs ) internal pure returns (address addr) { require(_bs.length == 20, "bytes length does not match address"); assembly { // for _bs, first word store _bs.length, second word store _bs.value // load 32 bytes from mem[_bs+20], convert it into Uint160, meaning we take last 20 bytes as addr (address). addr := mload(add(_bs, 0x14)) // data within slot is lower-order aligned: https://stackoverflow.com/questions/66819732/state-variables-in-storage-lower-order-aligned-what-does-this-sentence-in-the } } function addressToBytes( address _addr ) internal pure returns (bytes memory bs) { assembly { bs := mload(0x40) mstore(bs, 0x14) mstore(add(bs, 0x20), shl(96, _addr)) mstore(0x40, add(bs, 0x40)) } } function sliceToBytes32( bytes memory _bytes, uint256 _start ) internal pure returns (bytes32 result) { require(_bytes.length >= (_start + 32)); assembly { result := mload(add(add(_bytes, 0x20), _start)) } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory tempBytes) { require(_bytes.length >= (_start + _length)); assembly { switch iszero(_length) case 0 { tempBytes := mload(0x40) let lengthmod := and(_length, 31) let iz := iszero(lengthmod) let mc := add(add(tempBytes, lengthmod), mul(0x20, iz)) let end := add(mc, _length) for { let cc := add( add(add(_bytes, lengthmod), mul(0x20, iz)), _start ) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } } function bytesToUint256( bytes memory _bs ) internal pure returns (uint256 value) { require(_bs.length == 32, "bytes length is not 32."); assembly { value := mload(add(_bs, 0x20)) } } function uint256ToBytes( uint256 _value ) internal pure returns (bytes memory bs) { assembly { bs := mload(0x40) mstore(bs, 0x20) mstore(add(bs, 0x20), _value) mstore(0x40, add(bs, 0x40)) } } function containMAddresses( address[] memory _keepers, address[] memory _signers, uint256 _m ) internal pure returns (bool) { uint256 m = 0; for (uint256 i = 0; i < _signers.length; i++) { for (uint256 j = 0; j < _keepers.length; j++) { if (_signers[i] == _keepers[j]) { m++; if (j < _keepers.length) { _keepers[j] = _keepers[_keepers.length - 1]; } assembly { mstore(_keepers, sub(mload(_keepers), 1)) } break; } } } return m >= _m; } uint256 constant SIGNATURE_LEN = 65; function verifySigs( bytes32 hash, bytes memory _sigs, address[] memory _keepers, uint256 _m ) internal pure returns (bool) { uint256 sigCount = _sigs.length / SIGNATURE_LEN; address[] memory signers = new address[](sigCount); bytes32 r; bytes32 s; uint8 v; for (uint256 i = 0; i < sigCount; i++) { r = sliceToBytes32(_sigs, i * SIGNATURE_LEN); s = sliceToBytes32(_sigs, i * SIGNATURE_LEN + 32); v = uint8(_sigs[i * SIGNATURE_LEN + 64]); signers[i] = ecrecover(hash, v, r, s); if (signers[i] == address(0)) { return false; } } return containMAddresses(_keepers, signers, _m); } function dedupAddress( address[] memory _dup ) internal pure returns (address[] memory) { address[] memory dedup = new address[](_dup.length); uint256 idx = 0; bool dup; for (uint256 i = 0; i < _dup.length; i++) { dup = false; for (uint256 j = 0; j < dedup.length; j++) { if (_dup[i] == dedup[j]) { dup = true; break; } } if (!dup) { dedup[idx] = _dup[i]; idx += 1; } } assembly { mstore(dedup, idx) } return dedup; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div( and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2 ) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // fslot can contain both the length and contents of the array // if slength < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage // slength != 0 if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint(mc < end) + cb == 2) for { } eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; /** * @dev Wrappers over encoding and serialization operation into bytes from bassic types in Solidity for PolyNetwork cross chain utility. * * Encode basic types in Solidity into bytes easily. It's designed to be used * for PolyNetwork cross chain application, and the encoding rules on Ethereum chain * and the decoding rules on other chains should be consistent. Here we * follow the underlying serialization rule with implementation found here: * https://github.com/polynetwork/poly/blob/master/common/zero_copy_sink.go * * Using this library instead of the unchecked serialization method can help reduce * the risk of serious bugs and handfule, so it's recommended to use it. * * Please note that risk can be minimized, yet not eliminated. */ library ZeroCopySink { /* @notice Convert boolean value into bytes * @param b The boolean value * @return Converted bytes array */ function WriteBool(bool b) internal pure returns (bytes memory) { bytes memory buff; assembly { buff := mload(0x40) mstore(buff, 1) switch iszero(b) case 1 { mstore(add(buff, 0x20), shl(248, 0x00)) // mstore8(add(buff, 0x20), 0x00) } default { mstore(add(buff, 0x20), shl(248, 0x01)) // mstore8(add(buff, 0x20), 0x01) } mstore(0x40, add(buff, 0x21)) } return buff; } /* @notice Convert byte value into bytes * @param b The byte value * @return Converted bytes array */ function WriteByte(bytes1 b) internal pure returns (bytes memory) { return WriteUint8(uint8(b)); } /* @notice Convert uint8 value into bytes * @param v The uint8 value * @return Converted bytes array */ function WriteUint8(uint8 v) internal pure returns (bytes memory) { bytes memory buff; assembly { buff := mload(0x40) mstore(buff, 1) mstore(add(buff, 0x20), shl(248, v)) // mstore(add(buff, 0x20), byte(0x1f, v)) mstore(0x40, add(buff, 0x21)) } return buff; } /* @notice Convert uint16 value into bytes * @param v The uint16 value * @return Converted bytes array */ function WriteUint16(uint16 v) internal pure returns (bytes memory) { bytes memory buff; assembly { buff := mload(0x40) let byteLen := 0x02 mstore(buff, byteLen) for { let mindex := 0x00 let vindex := 0x1f } lt(mindex, byteLen) { mindex := add(mindex, 0x01) vindex := sub(vindex, 0x01) } { mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) } mstore(0x40, add(buff, 0x22)) } return buff; } /* @notice Convert uint32 value into bytes * @param v The uint32 value * @return Converted bytes array */ function WriteUint32(uint32 v) internal pure returns (bytes memory) { bytes memory buff; assembly { buff := mload(0x40) let byteLen := 0x04 mstore(buff, byteLen) for { let mindex := 0x00 let vindex := 0x1f } lt(mindex, byteLen) { mindex := add(mindex, 0x01) vindex := sub(vindex, 0x01) } { mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) } mstore(0x40, add(buff, 0x24)) } return buff; } /* @notice Convert uint64 value into bytes * @param v The uint64 value * @return Converted bytes array */ function WriteUint64(uint64 v) internal pure returns (bytes memory) { bytes memory buff; assembly { buff := mload(0x40) let byteLen := 0x08 mstore(buff, byteLen) for { let mindex := 0x00 let vindex := 0x1f } lt(mindex, byteLen) { mindex := add(mindex, 0x01) vindex := sub(vindex, 0x01) } { mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) } mstore(0x40, add(buff, 0x28)) } return buff; } /* @notice Convert limited uint256 value into bytes * @param v The uint256 value * @return Converted bytes array */ function WriteUint255(uint256 v) internal pure returns (bytes memory) { require( v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds uint255 range" ); bytes memory buff; assembly { buff := mload(0x40) let byteLen := 0x20 mstore(buff, byteLen) for { let mindex := 0x00 let vindex := 0x1f } lt(mindex, byteLen) { mindex := add(mindex, 0x01) vindex := sub(vindex, 0x01) } { mstore8(add(add(buff, 0x20), mindex), byte(vindex, v)) } mstore(0x40, add(buff, 0x40)) } return buff; } /* @notice Encode bytes format data into bytes * @param data The bytes array data * @return Encoded bytes array */ function WriteVarBytes( bytes memory data ) internal pure returns (bytes memory) { uint64 l = uint64(data.length); return abi.encodePacked(WriteVarUint(l), data); } function WriteVarUint(uint64 v) internal pure returns (bytes memory) { if (v < 0xFD) { return WriteUint8(uint8(v)); } else if (v <= 0xFFFF) { return abi.encodePacked(WriteByte(0xFD), WriteUint16(uint16(v))); } else if (v <= 0xFFFFFFFF) { return abi.encodePacked(WriteByte(0xFE), WriteUint32(uint32(v))); } else { return abi.encodePacked(WriteByte(0xFF), WriteUint64(uint64(v))); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; /** * @dev Wrappers over decoding and deserialization operation from bytes into bassic types in Solidity for PolyNetwork cross chain utility. * * Decode into basic types in Solidity from bytes easily. It's designed to be used * for PolyNetwork cross chain application, and the decoding rules on Ethereum chain * and the encoding rule on other chains should be consistent, and . Here we * follow the underlying deserialization rule with implementation found here: * https://github.com/polynetwork/poly/blob/master/common/zero_copy_source.go * * Using this library instead of the unchecked serialization method can help reduce * the risk of serious bugs and handfule, so it's recommended to use it. * * Please note that risk can be minimized, yet not eliminated. */ library ZeroCopySource { /* @notice Read next byte as boolean type starting at offset from buff * @param buff Source bytes array * @param offset The position from where we read the boolean value * @return The the read boolean value and new offset */ function NextBool( bytes memory buff, uint256 offset ) internal pure returns (bool, uint256) { require( offset + 1 <= buff.length && offset < offset + 1, "Offset exceeds limit" ); // byte === bytes1 bytes1 v; assembly { v := mload(add(add(buff, 0x20), offset)) } bool value; if (v == 0x01) { value = true; } else if (v == 0x00) { value = false; } else { revert("NextBool value error"); } return (value, offset + 1); } /* @notice Read next byte starting at offset from buff * @param buff Source bytes array * @param offset The position from where we read the byte value * @return The read byte value and new offset */ function NextByte( bytes memory buff, uint256 offset ) internal pure returns (bytes1, uint256) { require( offset + 1 <= buff.length && offset < offset + 1, "NextByte, Offset exceeds maximum" ); bytes1 v; assembly { v := mload(add(add(buff, 0x20), offset)) } return (v, offset + 1); } /* @notice Read next byte as uint8 starting at offset from buff * @param buff Source bytes array * @param offset The position from where we read the byte value * @return The read uint8 value and new offset */ function NextUint8( bytes memory buff, uint256 offset ) internal pure returns (uint8, uint256) { require( offset + 1 <= buff.length && offset < offset + 1, "NextUint8, Offset exceeds maximum" ); uint8 v; assembly { let tmpbytes := mload(0x40) let bvalue := mload(add(add(buff, 0x20), offset)) mstore8(tmpbytes, byte(0, bvalue)) mstore(0x40, add(tmpbytes, 0x01)) v := mload(sub(tmpbytes, 0x1f)) } return (v, offset + 1); } /* @notice Read next two bytes as uint16 type starting from offset * @param buff Source bytes array * @param offset The position from where we read the uint16 value * @return The read uint16 value and updated offset */ function NextUint16( bytes memory buff, uint256 offset ) internal pure returns (uint16, uint256) { require( offset + 2 <= buff.length && offset < offset + 2, "NextUint16, offset exceeds maximum" ); uint16 v; assembly { let tmpbytes := mload(0x40) let bvalue := mload(add(add(buff, 0x20), offset)) mstore8(tmpbytes, byte(0x01, bvalue)) mstore8(add(tmpbytes, 0x01), byte(0, bvalue)) mstore(0x40, add(tmpbytes, 0x02)) v := mload(sub(tmpbytes, 0x1e)) } return (v, offset + 2); } /* @notice Read next four bytes as uint32 type starting from offset * @param buff Source bytes array * @param offset The position from where we read the uint32 value * @return The read uint32 value and updated offset */ function NextUint32( bytes memory buff, uint256 offset ) internal pure returns (uint32, uint256) { require( offset + 4 <= buff.length && offset < offset + 4, "NextUint32, offset exceeds maximum" ); uint32 v; assembly { let tmpbytes := mload(0x40) let byteLen := 0x04 for { let tindex := 0x00 let bindex := sub(byteLen, 0x01) let bvalue := mload(add(add(buff, 0x20), offset)) } lt(tindex, byteLen) { tindex := add(tindex, 0x01) bindex := sub(bindex, 0x01) } { mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) } mstore(0x40, add(tmpbytes, byteLen)) v := mload(sub(tmpbytes, sub(0x20, byteLen))) } return (v, offset + 4); } /* @notice Read next eight bytes as uint64 type starting from offset * @param buff Source bytes array * @param offset The position from where we read the uint64 value * @return The read uint64 value and updated offset */ function NextUint64( bytes memory buff, uint256 offset ) internal pure returns (uint64, uint256) { require( offset + 8 <= buff.length && offset < offset + 8, "NextUint64, offset exceeds maximum" ); uint64 v; assembly { let tmpbytes := mload(0x40) let byteLen := 0x08 for { let tindex := 0x00 let bindex := sub(byteLen, 0x01) let bvalue := mload(add(add(buff, 0x20), offset)) } lt(tindex, byteLen) { tindex := add(tindex, 0x01) bindex := sub(bindex, 0x01) } { mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) } mstore(0x40, add(tmpbytes, byteLen)) v := mload(sub(tmpbytes, sub(0x20, byteLen))) } return (v, offset + 8); } /* @notice Read next 32 bytes as uint256 type starting from offset, there are limits considering the numerical limits in multi-chain * @param buff Source bytes array * @param offset The position from where we read the uint256 value * @return The read uint256 value and updated offset */ function NextUint255( bytes memory buff, uint256 offset ) internal pure returns (uint256, uint256) { require( offset + 32 <= buff.length && offset < offset + 32, "NextUint255, offset exceeds maximum" ); uint256 v; assembly { let tmpbytes := mload(0x40) let byteLen := 0x20 for { let tindex := 0x00 let bindex := sub(byteLen, 0x01) let bvalue := mload(add(add(buff, 0x20), offset)) } lt(tindex, byteLen) { tindex := add(tindex, 0x01) bindex := sub(bindex, 0x01) } { mstore8(add(tmpbytes, tindex), byte(bindex, bvalue)) } mstore(0x40, add(tmpbytes, byteLen)) v := mload(tmpbytes) } require( v <= 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, "Value exceeds the range" ); return (v, offset + 32); } /* @notice Read next variable bytes starting from offset, the decoding rule coming from multi-chain * @param buff Source bytes array * @param offset The position from where we read the bytes value * @return The read variable bytes array value and updated offset */ function NextVarBytes( bytes memory buff, uint256 offset ) internal pure returns (bytes memory, uint256) { uint len; (len, offset) = NextVarUint(buff, offset); require( offset + len <= buff.length && offset < offset + len, "NextVarBytes, offset exceeds maximum" ); bytes memory tempBytes; assembly { switch iszero(len) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(len, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add( add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)) ) let end := add(mc, len) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add( add(add(buff, lengthmod), mul(0x20, iszero(lengthmod))), offset ) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, len) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return (tempBytes, offset + len); } /* @notice Read next 32 bytes starting from offset, * @param buff Source bytes array * @param offset The position from where we read the bytes value * @return The read bytes32 value and updated offset */ function NextHash( bytes memory buff, uint256 offset ) internal pure returns (bytes32, uint256) { require( offset + 32 <= buff.length && offset < offset + 32, "NextHash, offset exceeds maximum" ); bytes32 v; assembly { v := mload(add(buff, add(offset, 0x20))) } return (v, offset + 32); } /* @notice Read next 20 bytes starting from offset, * @param buff Source bytes array * @param offset The position from where we read the bytes value * @return The read bytes20 value and updated offset */ function NextBytes20( bytes memory buff, uint256 offset ) internal pure returns (bytes20, uint256) { require( offset + 20 <= buff.length && offset < offset + 20, "NextBytes20, offset exceeds maximum" ); bytes20 v; assembly { v := mload(add(buff, add(offset, 0x20))) } return (v, offset + 20); } function NextVarUint( bytes memory buff, uint256 offset ) internal pure returns (uint, uint256) { bytes1 v; (v, offset) = NextByte(buff, offset); uint value; if (v == 0xFD) { // return NextUint16(buff, offset); (value, offset) = NextUint16(buff, offset); require( value >= 0xFD && value <= 0xFFFF, "NextUint16, value outside range" ); return (value, offset); } else if (v == 0xFE) { // return NextUint32(buff, offset); (value, offset) = NextUint32(buff, offset); require( value > 0xFFFF && value <= 0xFFFFFFFF, "NextVarUint, value outside range" ); return (value, offset); } else if (v == 0xFF) { // return NextUint64(buff, offset); (value, offset) = NextUint64(buff, offset); require(value > 0xFFFFFFFF, "NextVarUint, value outside range"); return (value, offset); } else { // return (uint8(v), offset); value = uint8(v); require(value < 0xFD, "NextVarUint, value outside range"); return (value, offset); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface ILockProxy { function bridgeProxy() external view returns (address); function lock( address fromAssetHash, uint16 toChainId, bytes calldata toAddress, uint256 amount ) external payable returns (bool); }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fromAssetHash","type":"address"},{"indexed":false,"internalType":"uint64","name":"toChainId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"targetProxyHash","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"initialAmount","type":"uint256"}],"name":"BindAssetEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"toChainId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"targetProxyHash","type":"bytes"}],"name":"BindProxyEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"fromAssetHash","type":"address"},{"indexed":false,"internalType":"address","name":"fromAddress","type":"address"},{"indexed":false,"internalType":"uint64","name":"toChainId","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"toAssetHash","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LockEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bridgeProxy","type":"address"}],"name":"SetBridgeProxyEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"toAssetHash","type":"address"},{"indexed":false,"internalType":"address","name":"toAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnlockEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"assetHashMap","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromAssetHash","type":"address"},{"internalType":"uint64","name":"toChainId","type":"uint64"},{"internalType":"bytes","name":"toAssetHash","type":"bytes"}],"name":"bindAssetHash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"toChainId","type":"uint64"},{"internalType":"bytes","name":"targetProxyHash","type":"bytes"}],"name":"bindProxyHash","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridgeProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromAssetHash","type":"address"}],"name":"getBalanceFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromAssetHash","type":"address"},{"internalType":"uint16","name":"toChainId","type":"uint16"},{"internalType":"bytes","name":"toAddress","type":"bytes"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"onReceive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"proxyHashMap","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bridgeProxy","type":"address"}],"name":"setBridgeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001a3361002c565b6000805460ff60a01b1916905561007c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61252c8061008b6000396000f3fe6080604052600436106100e85760003560e01c8063688d0a281161008a5780639e5767aa116100595780639e5767aa14610262578063a3d4485b14610282578063a571e184146102a2578063f2fde38b146102c257600080fd5b8063688d0a28146101e6578063715018a6146102065780638456cb591461021b5780638da5cb5b1461023057600080fd5b80633f4ba83a116100c65780633f4ba83a146101555780634f7d98081461016c57806359c589a1146101995780635c975abb146101c757600080fd5b8063155ae4df146100ed5780633348f63b14610115578063379b98f614610135575b600080fd5b6101006100fb366004611fb4565b6102e2565b60405190151581526020015b60405180910390f35b34801561012157600080fd5b50610100610130366004612032565b6106a2565b34801561014157600080fd5b50610100610150366004612091565b610736565b34801561016157600080fd5b5061016a6107ac565b005b34801561017857600080fd5b5061018c6101873660046120de565b6107be565b60405161010c919061216b565b3480156101a557600080fd5b506101b96101b436600461217e565b610863565b60405190815260200161010c565b3480156101d357600080fd5b50600054600160a01b900460ff16610100565b3480156101f257600080fd5b506101006102013660046121dc565b6108f0565b34801561021257600080fd5b5061016a610ba6565b34801561022757600080fd5b5061016a610bb8565b34801561023c57600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161010c565b34801561026e57600080fd5b5061018c61027d366004612265565b610bc8565b34801561028e57600080fd5b5060015461024a906001600160a01b031681565b3480156102ae57600080fd5b5061016a6102bd36600461217e565b610be1565b3480156102ce57600080fd5b5061016a6102dd36600461217e565b610c3d565b6000816000036103235760405162461bcd60e51b815260206004820152600760248201526608585b5bdd5b9d60ca1b60448201526064015b60405180910390fd5b61032d8583610cb6565b6103705760405162461bcd60e51b81526020600482015260146024820152730857dd1c985b9cd9995c951bd0dbdb9d1c9858dd60621b604482015260640161031a565b6001600160a01b038516600090815260026020908152604080832061ffff88168452909152812080546103a290612280565b80601f01602080910402602001604051908101604052809291908181526020018280546103ce90612280565b801561041b5780601f106103f05761010080835404028352916020019161041b565b820191906000526020600020905b8154815290600101906020018083116103fe57829003601f168201915b5050505050905080516000036104625760405162461bcd60e51b815260206004820152600c60248201526b042e8de82e6e6cae890c2e6d60a31b604482015260640161031a565b6040805160608101825282815260208101869052908101849052600061048782610e5c565b90506000600160009054906101000a90046001600160a01b03166001600160a01b031663d7dfa0dd6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156104e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906122ba565b61ffff891660009081526003602052604081208054929350909161052790612280565b80601f016020809104026020016040519081016040528092919081815260200182805461055390612280565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b5050505050905080516000036105e75760405162461bcd60e51b815260206004820152600c60248201526b042e8dea0e4def0f290c2e6d60a31b604482015260640161031a565b60405163f2109a3f60e01b81526001600160a01b0383169063f2109a3f90610617908c90859088906004016122d7565b600060405180830381600087803b15801561063157600080fd5b505af1158015610645573d6000803e3d6000fd5b505050507f8636abd6d0e464fe725a13346c7ac779b73561c705506044a2e6b2cdb1295ea58a6106723390565b8b888c8c60405161068896959493929190612310565b60405180910390a16001955050505050505b949350505050565b60006106ac610eaf565b6001600160a01b03841660009081526002602090815260408083206001600160401b0387168452825290912083516106e692850190611e52565b507f1628c8374c1bdfeb2275fd9f4c90562fd3fae974783dc522c8234e36abcfc58e84848461071488610863565b604051610724949392919061236c565b60405180910390a15060019392505050565b6000610740610eaf565b6001600160401b0383166000908152600360209081526040909120835161076992850190611e52565b507fdacd7d303272a3b58aec6620d6d1fb588f4996a5b46858ed437f1c34348f2d0f838360405161079b9291906123b0565b60405180910390a150600192915050565b6107b4610eaf565b6107bc610f09565b565b6002602090815260009283526040808420909152908252902080546107e290612280565b80601f016020809104026020016040519081016040528092919081815260200182805461080e90612280565b801561085b5780601f106108305761010080835404028352916020019161085b565b820191906000526020600020905b81548152906001019060200180831161083e57829003601f168201915b505050505081565b60006001600160a01b03821661087a575050303190565b6040516370a0823160e01b815230600482015282906001600160a01b038216906370a0823190602401602060405180830381865afa1580156108c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e491906123d2565b9392505050565b919050565b6001546000906001600160a01b0316336001600160a01b0316146109565760405162461bcd60e51b815260206004820152601d60248201527f6d73672e73656e646572206973206e6f742062726964676550726f7879000000604482015260640161031a565b60008590036109bb5760405162461bcd60e51b815260206004820152602b60248201527f66726f6d2070726f787920636f6e747261637420616464726573732063616e6e60448201526a6f7420626520656d70747960a81b606482015260840161031a565b60006109fc84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f5e92505050565b805151909150600003610a515760405162461bcd60e51b815260206004820152601b60248201527f746f4173736574486173682063616e6e6f7420626520656d7074790000000000604482015260640161031a565b6000610a608260000151610fe2565b9050816020015151600003610ab75760405162461bcd60e51b815260206004820152601960248201527f746f416464726573732063616e6e6f7420626520656d70747900000000000000604482015260640161031a565b6000610ac68360200151610fe2565b9050610ad782828560400151611049565b610b495760405162461bcd60e51b815260206004820152603c60248201527f7472616e736665722061737365742066726f6d206c6f636b5f70726f7879206360448201527f6f6e747261637420746f20746f41646472657373206661696c65642100000000606482015260840161031a565b60408084015181516001600160a01b03808616825284166020820152918201527fd90288730b87c2b8e0c45bd82260fd22478aba30ae1c4d578b8daba9261604df9060600160405180910390a15060019998505050505050505050565b610bae610eaf565b6107bc6000611127565b610bc0610eaf565b6107bc611177565b600360205260009081526040902080546107e290612280565b610be9610eaf565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe7868adde58dcdcc1e045f5178e8e7a14f86110d7f2c55ff0712e906daa712209060200160405180910390a150565b610c45610eaf565b6001600160a01b038116610caa5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161031a565b610cb381611127565b50565b60006001600160a01b038316610d865734600003610d205760405162461bcd60e51b815260206004820152602160248201527f7472616e736665727265642065746865722063616e6e6f74206265207a65726f6044820152602160f81b606482015260840161031a565b813414610d815760405162461bcd60e51b815260206004820152602960248201527f7472616e73666572726564206574686572206973206e6f7420657175616c20746044820152686f20616d6f756e742160b81b606482015260840161031a565b610e53565b3415610ddf5760405162461bcd60e51b815260206004820152602260248201527f74686572652073686f756c64206265206e6f206574686572207472616e736665604482015261722160f01b606482015260840161031a565b610deb833330856111ba565b610e535760405162461bcd60e51b815260206004820152603360248201527f7472616e7366657220657263323020617373657420746f206c6f636b5f70726f604482015272787920636f6e7472616374206661696c65642160681b606482015260840161031a565b50600192915050565b606080610e6c83600001516111de565b610e7984602001516111de565b610e868560400151611215565b604051602001610e98939291906123eb565b60408051601f198184030181529190529392505050565b6000546001600160a01b031633146107bc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161031a565b610f116112ad565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b610f8260405180606001604052806060815260200160608152602001600081525090565b610fa660405180606001604052806060815260200160608152602001600081525090565b6000610fb284826112fd565b9083529050610fc184826112fd565b60208401919091529050610fd5848261140b565b5060408301525092915050565b600081516014146110415760405162461bcd60e51b815260206004820152602360248201527f6279746573206c656e67746820646f6573206e6f74206d61746368206164647260448201526265737360e81b606482015260840161031a565b506014015190565b60006001600160a01b038416611095576040516001600160a01b0384169083156108fc029084906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b5061111d565b6110a084848461153b565b61111d5760405162461bcd60e51b815260206004820152604260248201527f7472616e736665722065726332302061737365742066726f6d206c6f636b5f7060448201527f726f787920636f6e747261637420746f20746f41646472657373206661696c65606482015261642160f01b608482015260a40161031a565b5060019392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61117f61155d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610f413390565b6000846111d26001600160a01b0382168686866115aa565b50600195945050505050565b80516060906111ec8161161b565b836040516020016111fe92919061242e565b604051602081830303815290604052915050919050565b60606001600160ff1b0382111561126e5760405162461bcd60e51b815260206004820152601b60248201527f56616c756520657863656564732075696e743235352072616e67650000000000604482015260640161031a565b60405160208082526000601f5b8282101561129d5785811a82602086010153600191909101906000190161127b565b5050506040818101905292915050565b600054600160a01b900460ff166107bc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161031a565b606060008061130c85856116e2565b865190955090915061131e828661245d565b111580156113345750611331818561245d565b84105b61138c5760405162461bcd60e51b8152602060048201526024808201527f4e65787456617242797465732c206f66667365742065786365656473206d6178604482015263696d756d60e01b606482015260840161031a565b6060811580156113a7576040519150602082016040526113f1565b6040519150601f8316801560200281840101848101888315602002848c0101015b818310156113e05780518352602092830192016113c8565b5050848452601f01601f1916604052505b50806113fd838761245d565b9350935050505b9250929050565b600080835183602061141d919061245d565b11158015611434575061143183602061245d565b83105b61148c5760405162461bcd60e51b815260206004820152602360248201527f4e65787455696e743235352c206f66667365742065786365656473206d6178696044820152626d756d60e81b606482015260840161031a565b600060405160206000600182038760208a0101515b838310156114c15780821a838601536001830192506001820391506114a1565b50505081016040525190506001600160ff1b038111156115235760405162461bcd60e51b815260206004820152601760248201527f56616c75652065786365656473207468652072616e6765000000000000000000604482015260640161031a565b8061152f85602061245d565b92509250509250929050565b6000836115526001600160a01b0382168585611855565b506001949350505050565b600054600160a01b900460ff16156107bc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161031a565b6040516001600160a01b03808516602483015283166044820152606481018290526116159085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261188a565b50505050565b606060fd826001600160401b0316101561164f57604080516001815260f884901b6020820152602181019091525b92915050565b61ffff826001600160401b03161161169e5761166e60fd60f81b61195c565b61167783611983565b60405160200161168892919061242e565b6040516020818303038152906040529050919050565b63ffffffff826001600160401b0316116116c8576116bf607f60f91b61195c565b611677836119c6565b6116d96001600160f81b031961195c565b61167783611a09565b60008060006116f18585611a4c565b9450905060006001600160f81b0319821660fd60f81b03611789576117168686611ad4565b955061ffff16905060fd8110801590611731575061ffff8111155b61177d5760405162461bcd60e51b815260206004820152601f60248201527f4e65787455696e7431362c2076616c7565206f7574736964652072616e676500604482015260640161031a565b92508391506114049050565b6001600160f81b03198216607f60f91b036117e3576117a88686611b8d565b955063ffffffff16905061ffff811180156117c7575063ffffffff8111155b61177d5760405162461bcd60e51b815260040161031a90612483565b6001600160f81b0319808316900361182f576117ff8686611c5e565b95506001600160401b0316905063ffffffff811161177d5760405162461bcd60e51b815260040161031a90612483565b5060f881901c60fd811061177d5760405162461bcd60e51b815260040161031a90612483565b6040516001600160a01b03831660248201526044810182905261188590849063a9059cbb60e01b906064016115de565b505050565b60006118df826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611d2f9092919063ffffffff16565b80519091501561188557808060200190518101906118fd91906124b8565b6118855760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161031a565b60408051600181526001600160f81b03198316602082015260218101909152606090611649565b6040516002808252606091906000601f5b828210156119b65785811a826020860101536001919091019060001901611994565b5050506022810160405292915050565b6040516004808252606091906000601f5b828210156119f95785811a8260208601015360019190910190600019016119d7565b5050506024810160405292915050565b6040516008808252606091906000601f5b82821015611a3c5785811a826020860101536001919091019060001901611a1a565b5050506028810160405292915050565b6000808351836001611a5e919061245d565b11158015611a755750611a7283600161245d565b83105b611ac15760405162461bcd60e51b815260206004820181905260248201527f4e657874427974652c204f66667365742065786365656473206d6178696d756d604482015260640161031a565b838301602001518061152f85600161245d565b6000808351836002611ae6919061245d565b11158015611afd5750611afa83600261245d565b83105b611b545760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7431362c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b6000604051846020870101518060011a82538060001a60018301535060028101604052601e8103519150508084600261152f919061245d565b6000808351836004611b9f919061245d565b11158015611bb65750611bb383600461245d565b83105b611c0d5760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7433322c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b600060405160046000600182038760208a0101515b83831015611c425780821a83860153600183019250600182039150611c22565b505050016040819052601f19015190508061152f85600461245d565b6000808351836008611c70919061245d565b11158015611c875750611c8483600861245d565b83105b611cde5760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7436342c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b600060405160086000600182038760208a0101515b83831015611d135780821a83860153600183019250600182039150611cf3565b505050016040819052601f19015190508061152f85600861245d565b606061069a848460008585600080866001600160a01b03168587604051611d5691906124da565b60006040518083038185875af1925050503d8060008114611d93576040519150601f19603f3d011682016040523d82523d6000602084013e611d98565b606091505b5091509150611da987838387611db4565b979650505050505050565b60608315611e23578251600003611e1c576001600160a01b0385163b611e1c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161031a565b508161069a565b61069a8383815115611e385781518083602001fd5b8060405162461bcd60e51b815260040161031a919061216b565b828054611e5e90612280565b90600052602060002090601f016020900481019282611e805760008555611ec6565b82601f10611e9957805160ff1916838001178555611ec6565b82800160010185558215611ec6579182015b82811115611ec6578251825591602001919060010190611eab565b50611ed2929150611ed6565b5090565b5b80821115611ed25760008155600101611ed7565b6001600160a01b0381168114610cb357600080fd5b803561ffff811681146108eb57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f830112611f3957600080fd5b81356001600160401b0380821115611f5357611f53611f12565b604051601f8301601f19908116603f01168101908282118183101715611f7b57611f7b611f12565b81604052838152866020858801011115611f9457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215611fca57600080fd5b8435611fd581611eeb565b9350611fe360208601611f00565b925060408501356001600160401b03811115611ffe57600080fd5b61200a87828801611f28565b949793965093946060013593505050565b80356001600160401b03811681146108eb57600080fd5b60008060006060848603121561204757600080fd5b833561205281611eeb565b92506120606020850161201b565b915060408401356001600160401b0381111561207b57600080fd5b61208786828701611f28565b9150509250925092565b600080604083850312156120a457600080fd5b6120ad8361201b565b915060208301356001600160401b038111156120c857600080fd5b6120d485828601611f28565b9150509250929050565b600080604083850312156120f157600080fd5b82356120fc81611eeb565b915061210a6020840161201b565b90509250929050565b60005b8381101561212e578181015183820152602001612116565b838111156116155750506000910152565b60008151808452612157816020860160208601612113565b601f01601f19169290920160200192915050565b6020815260006108e4602083018461213f565b60006020828403121561219057600080fd5b81356108e481611eeb565b60008083601f8401126121ad57600080fd5b5081356001600160401b038111156121c457600080fd5b60208301915083602082850101111561140457600080fd5b600080600080600080608087890312156121f557600080fd5b6121fe87611f00565b955060208701356001600160401b038082111561221a57600080fd5b6122268a838b0161219b565b909750955060408901359450606089013591508082111561224657600080fd5b5061225389828a0161219b565b979a9699509497509295939492505050565b60006020828403121561227757600080fd5b6108e48261201b565b600181811c9082168061229457607f821691505b6020821081036122b457634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156122cc57600080fd5b81516108e481611eeb565b61ffff841681526060602082015260006122f4606083018561213f565b8281036040840152612306818561213f565b9695505050505050565b6001600160a01b0387811682528616602082015261ffff8516604082015260c0606082018190526000906123469083018661213f565b8281036080840152612358818661213f565b9150508260a0830152979650505050505050565b6001600160a01b03851681526001600160401b038416602082015260806040820181905260009061239f9083018561213f565b905082606083015295945050505050565b6001600160401b038316815260406020820152600061069a604083018461213f565b6000602082840312156123e457600080fd5b5051919050565b600084516123fd818460208901612113565b845190830190612411818360208901612113565b8451910190612424818360208801612113565b0195945050505050565b60008351612440818460208801612113565b835190830190612454818360208801612113565b01949350505050565b6000821982111561247e57634e487b7160e01b600052601160045260246000fd5b500190565b6020808252818101527f4e65787456617255696e742c2076616c7565206f7574736964652072616e6765604082015260600190565b6000602082840312156124ca57600080fd5b815180151581146108e457600080fd5b600082516124ec818460208701612113565b919091019291505056fea264697066735822122085285d5922d98e0b2fdd211a52f44749cf5daf1e0c04267e480adf0cc1de89cf64736f6c634300080d0033
Deployed Bytecode
0x6080604052600436106100e85760003560e01c8063688d0a281161008a5780639e5767aa116100595780639e5767aa14610262578063a3d4485b14610282578063a571e184146102a2578063f2fde38b146102c257600080fd5b8063688d0a28146101e6578063715018a6146102065780638456cb591461021b5780638da5cb5b1461023057600080fd5b80633f4ba83a116100c65780633f4ba83a146101555780634f7d98081461016c57806359c589a1146101995780635c975abb146101c757600080fd5b8063155ae4df146100ed5780633348f63b14610115578063379b98f614610135575b600080fd5b6101006100fb366004611fb4565b6102e2565b60405190151581526020015b60405180910390f35b34801561012157600080fd5b50610100610130366004612032565b6106a2565b34801561014157600080fd5b50610100610150366004612091565b610736565b34801561016157600080fd5b5061016a6107ac565b005b34801561017857600080fd5b5061018c6101873660046120de565b6107be565b60405161010c919061216b565b3480156101a557600080fd5b506101b96101b436600461217e565b610863565b60405190815260200161010c565b3480156101d357600080fd5b50600054600160a01b900460ff16610100565b3480156101f257600080fd5b506101006102013660046121dc565b6108f0565b34801561021257600080fd5b5061016a610ba6565b34801561022757600080fd5b5061016a610bb8565b34801561023c57600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161010c565b34801561026e57600080fd5b5061018c61027d366004612265565b610bc8565b34801561028e57600080fd5b5060015461024a906001600160a01b031681565b3480156102ae57600080fd5b5061016a6102bd36600461217e565b610be1565b3480156102ce57600080fd5b5061016a6102dd36600461217e565b610c3d565b6000816000036103235760405162461bcd60e51b815260206004820152600760248201526608585b5bdd5b9d60ca1b60448201526064015b60405180910390fd5b61032d8583610cb6565b6103705760405162461bcd60e51b81526020600482015260146024820152730857dd1c985b9cd9995c951bd0dbdb9d1c9858dd60621b604482015260640161031a565b6001600160a01b038516600090815260026020908152604080832061ffff88168452909152812080546103a290612280565b80601f01602080910402602001604051908101604052809291908181526020018280546103ce90612280565b801561041b5780601f106103f05761010080835404028352916020019161041b565b820191906000526020600020905b8154815290600101906020018083116103fe57829003601f168201915b5050505050905080516000036104625760405162461bcd60e51b815260206004820152600c60248201526b042e8de82e6e6cae890c2e6d60a31b604482015260640161031a565b6040805160608101825282815260208101869052908101849052600061048782610e5c565b90506000600160009054906101000a90046001600160a01b03166001600160a01b031663d7dfa0dd6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156104e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050491906122ba565b61ffff891660009081526003602052604081208054929350909161052790612280565b80601f016020809104026020016040519081016040528092919081815260200182805461055390612280565b80156105a05780601f10610575576101008083540402835291602001916105a0565b820191906000526020600020905b81548152906001019060200180831161058357829003601f168201915b5050505050905080516000036105e75760405162461bcd60e51b815260206004820152600c60248201526b042e8dea0e4def0f290c2e6d60a31b604482015260640161031a565b60405163f2109a3f60e01b81526001600160a01b0383169063f2109a3f90610617908c90859088906004016122d7565b600060405180830381600087803b15801561063157600080fd5b505af1158015610645573d6000803e3d6000fd5b505050507f8636abd6d0e464fe725a13346c7ac779b73561c705506044a2e6b2cdb1295ea58a6106723390565b8b888c8c60405161068896959493929190612310565b60405180910390a16001955050505050505b949350505050565b60006106ac610eaf565b6001600160a01b03841660009081526002602090815260408083206001600160401b0387168452825290912083516106e692850190611e52565b507f1628c8374c1bdfeb2275fd9f4c90562fd3fae974783dc522c8234e36abcfc58e84848461071488610863565b604051610724949392919061236c565b60405180910390a15060019392505050565b6000610740610eaf565b6001600160401b0383166000908152600360209081526040909120835161076992850190611e52565b507fdacd7d303272a3b58aec6620d6d1fb588f4996a5b46858ed437f1c34348f2d0f838360405161079b9291906123b0565b60405180910390a150600192915050565b6107b4610eaf565b6107bc610f09565b565b6002602090815260009283526040808420909152908252902080546107e290612280565b80601f016020809104026020016040519081016040528092919081815260200182805461080e90612280565b801561085b5780601f106108305761010080835404028352916020019161085b565b820191906000526020600020905b81548152906001019060200180831161083e57829003601f168201915b505050505081565b60006001600160a01b03821661087a575050303190565b6040516370a0823160e01b815230600482015282906001600160a01b038216906370a0823190602401602060405180830381865afa1580156108c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e491906123d2565b9392505050565b919050565b6001546000906001600160a01b0316336001600160a01b0316146109565760405162461bcd60e51b815260206004820152601d60248201527f6d73672e73656e646572206973206e6f742062726964676550726f7879000000604482015260640161031a565b60008590036109bb5760405162461bcd60e51b815260206004820152602b60248201527f66726f6d2070726f787920636f6e747261637420616464726573732063616e6e60448201526a6f7420626520656d70747960a81b606482015260840161031a565b60006109fc84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f5e92505050565b805151909150600003610a515760405162461bcd60e51b815260206004820152601b60248201527f746f4173736574486173682063616e6e6f7420626520656d7074790000000000604482015260640161031a565b6000610a608260000151610fe2565b9050816020015151600003610ab75760405162461bcd60e51b815260206004820152601960248201527f746f416464726573732063616e6e6f7420626520656d70747900000000000000604482015260640161031a565b6000610ac68360200151610fe2565b9050610ad782828560400151611049565b610b495760405162461bcd60e51b815260206004820152603c60248201527f7472616e736665722061737365742066726f6d206c6f636b5f70726f7879206360448201527f6f6e747261637420746f20746f41646472657373206661696c65642100000000606482015260840161031a565b60408084015181516001600160a01b03808616825284166020820152918201527fd90288730b87c2b8e0c45bd82260fd22478aba30ae1c4d578b8daba9261604df9060600160405180910390a15060019998505050505050505050565b610bae610eaf565b6107bc6000611127565b610bc0610eaf565b6107bc611177565b600360205260009081526040902080546107e290612280565b610be9610eaf565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527fe7868adde58dcdcc1e045f5178e8e7a14f86110d7f2c55ff0712e906daa712209060200160405180910390a150565b610c45610eaf565b6001600160a01b038116610caa5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161031a565b610cb381611127565b50565b60006001600160a01b038316610d865734600003610d205760405162461bcd60e51b815260206004820152602160248201527f7472616e736665727265642065746865722063616e6e6f74206265207a65726f6044820152602160f81b606482015260840161031a565b813414610d815760405162461bcd60e51b815260206004820152602960248201527f7472616e73666572726564206574686572206973206e6f7420657175616c20746044820152686f20616d6f756e742160b81b606482015260840161031a565b610e53565b3415610ddf5760405162461bcd60e51b815260206004820152602260248201527f74686572652073686f756c64206265206e6f206574686572207472616e736665604482015261722160f01b606482015260840161031a565b610deb833330856111ba565b610e535760405162461bcd60e51b815260206004820152603360248201527f7472616e7366657220657263323020617373657420746f206c6f636b5f70726f604482015272787920636f6e7472616374206661696c65642160681b606482015260840161031a565b50600192915050565b606080610e6c83600001516111de565b610e7984602001516111de565b610e868560400151611215565b604051602001610e98939291906123eb565b60408051601f198184030181529190529392505050565b6000546001600160a01b031633146107bc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161031a565b610f116112ad565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b610f8260405180606001604052806060815260200160608152602001600081525090565b610fa660405180606001604052806060815260200160608152602001600081525090565b6000610fb284826112fd565b9083529050610fc184826112fd565b60208401919091529050610fd5848261140b565b5060408301525092915050565b600081516014146110415760405162461bcd60e51b815260206004820152602360248201527f6279746573206c656e67746820646f6573206e6f74206d61746368206164647260448201526265737360e81b606482015260840161031a565b506014015190565b60006001600160a01b038416611095576040516001600160a01b0384169083156108fc029084906000818181858888f1935050505015801561108f573d6000803e3d6000fd5b5061111d565b6110a084848461153b565b61111d5760405162461bcd60e51b815260206004820152604260248201527f7472616e736665722065726332302061737365742066726f6d206c6f636b5f7060448201527f726f787920636f6e747261637420746f20746f41646472657373206661696c65606482015261642160f01b608482015260a40161031a565b5060019392505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61117f61155d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610f413390565b6000846111d26001600160a01b0382168686866115aa565b50600195945050505050565b80516060906111ec8161161b565b836040516020016111fe92919061242e565b604051602081830303815290604052915050919050565b60606001600160ff1b0382111561126e5760405162461bcd60e51b815260206004820152601b60248201527f56616c756520657863656564732075696e743235352072616e67650000000000604482015260640161031a565b60405160208082526000601f5b8282101561129d5785811a82602086010153600191909101906000190161127b565b5050506040818101905292915050565b600054600160a01b900460ff166107bc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161031a565b606060008061130c85856116e2565b865190955090915061131e828661245d565b111580156113345750611331818561245d565b84105b61138c5760405162461bcd60e51b8152602060048201526024808201527f4e65787456617242797465732c206f66667365742065786365656473206d6178604482015263696d756d60e01b606482015260840161031a565b6060811580156113a7576040519150602082016040526113f1565b6040519150601f8316801560200281840101848101888315602002848c0101015b818310156113e05780518352602092830192016113c8565b5050848452601f01601f1916604052505b50806113fd838761245d565b9350935050505b9250929050565b600080835183602061141d919061245d565b11158015611434575061143183602061245d565b83105b61148c5760405162461bcd60e51b815260206004820152602360248201527f4e65787455696e743235352c206f66667365742065786365656473206d6178696044820152626d756d60e81b606482015260840161031a565b600060405160206000600182038760208a0101515b838310156114c15780821a838601536001830192506001820391506114a1565b50505081016040525190506001600160ff1b038111156115235760405162461bcd60e51b815260206004820152601760248201527f56616c75652065786365656473207468652072616e6765000000000000000000604482015260640161031a565b8061152f85602061245d565b92509250509250929050565b6000836115526001600160a01b0382168585611855565b506001949350505050565b600054600160a01b900460ff16156107bc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161031a565b6040516001600160a01b03808516602483015283166044820152606481018290526116159085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261188a565b50505050565b606060fd826001600160401b0316101561164f57604080516001815260f884901b6020820152602181019091525b92915050565b61ffff826001600160401b03161161169e5761166e60fd60f81b61195c565b61167783611983565b60405160200161168892919061242e565b6040516020818303038152906040529050919050565b63ffffffff826001600160401b0316116116c8576116bf607f60f91b61195c565b611677836119c6565b6116d96001600160f81b031961195c565b61167783611a09565b60008060006116f18585611a4c565b9450905060006001600160f81b0319821660fd60f81b03611789576117168686611ad4565b955061ffff16905060fd8110801590611731575061ffff8111155b61177d5760405162461bcd60e51b815260206004820152601f60248201527f4e65787455696e7431362c2076616c7565206f7574736964652072616e676500604482015260640161031a565b92508391506114049050565b6001600160f81b03198216607f60f91b036117e3576117a88686611b8d565b955063ffffffff16905061ffff811180156117c7575063ffffffff8111155b61177d5760405162461bcd60e51b815260040161031a90612483565b6001600160f81b0319808316900361182f576117ff8686611c5e565b95506001600160401b0316905063ffffffff811161177d5760405162461bcd60e51b815260040161031a90612483565b5060f881901c60fd811061177d5760405162461bcd60e51b815260040161031a90612483565b6040516001600160a01b03831660248201526044810182905261188590849063a9059cbb60e01b906064016115de565b505050565b60006118df826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611d2f9092919063ffffffff16565b80519091501561188557808060200190518101906118fd91906124b8565b6118855760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161031a565b60408051600181526001600160f81b03198316602082015260218101909152606090611649565b6040516002808252606091906000601f5b828210156119b65785811a826020860101536001919091019060001901611994565b5050506022810160405292915050565b6040516004808252606091906000601f5b828210156119f95785811a8260208601015360019190910190600019016119d7565b5050506024810160405292915050565b6040516008808252606091906000601f5b82821015611a3c5785811a826020860101536001919091019060001901611a1a565b5050506028810160405292915050565b6000808351836001611a5e919061245d565b11158015611a755750611a7283600161245d565b83105b611ac15760405162461bcd60e51b815260206004820181905260248201527f4e657874427974652c204f66667365742065786365656473206d6178696d756d604482015260640161031a565b838301602001518061152f85600161245d565b6000808351836002611ae6919061245d565b11158015611afd5750611afa83600261245d565b83105b611b545760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7431362c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b6000604051846020870101518060011a82538060001a60018301535060028101604052601e8103519150508084600261152f919061245d565b6000808351836004611b9f919061245d565b11158015611bb65750611bb383600461245d565b83105b611c0d5760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7433322c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b600060405160046000600182038760208a0101515b83831015611c425780821a83860153600183019250600182039150611c22565b505050016040819052601f19015190508061152f85600461245d565b6000808351836008611c70919061245d565b11158015611c875750611c8483600861245d565b83105b611cde5760405162461bcd60e51b815260206004820152602260248201527f4e65787455696e7436342c206f66667365742065786365656473206d6178696d604482015261756d60f01b606482015260840161031a565b600060405160086000600182038760208a0101515b83831015611d135780821a83860153600183019250600182039150611cf3565b505050016040819052601f19015190508061152f85600861245d565b606061069a848460008585600080866001600160a01b03168587604051611d5691906124da565b60006040518083038185875af1925050503d8060008114611d93576040519150601f19603f3d011682016040523d82523d6000602084013e611d98565b606091505b5091509150611da987838387611db4565b979650505050505050565b60608315611e23578251600003611e1c576001600160a01b0385163b611e1c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161031a565b508161069a565b61069a8383815115611e385781518083602001fd5b8060405162461bcd60e51b815260040161031a919061216b565b828054611e5e90612280565b90600052602060002090601f016020900481019282611e805760008555611ec6565b82601f10611e9957805160ff1916838001178555611ec6565b82800160010185558215611ec6579182015b82811115611ec6578251825591602001919060010190611eab565b50611ed2929150611ed6565b5090565b5b80821115611ed25760008155600101611ed7565b6001600160a01b0381168114610cb357600080fd5b803561ffff811681146108eb57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f830112611f3957600080fd5b81356001600160401b0380821115611f5357611f53611f12565b604051601f8301601f19908116603f01168101908282118183101715611f7b57611f7b611f12565b81604052838152866020858801011115611f9457600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215611fca57600080fd5b8435611fd581611eeb565b9350611fe360208601611f00565b925060408501356001600160401b03811115611ffe57600080fd5b61200a87828801611f28565b949793965093946060013593505050565b80356001600160401b03811681146108eb57600080fd5b60008060006060848603121561204757600080fd5b833561205281611eeb565b92506120606020850161201b565b915060408401356001600160401b0381111561207b57600080fd5b61208786828701611f28565b9150509250925092565b600080604083850312156120a457600080fd5b6120ad8361201b565b915060208301356001600160401b038111156120c857600080fd5b6120d485828601611f28565b9150509250929050565b600080604083850312156120f157600080fd5b82356120fc81611eeb565b915061210a6020840161201b565b90509250929050565b60005b8381101561212e578181015183820152602001612116565b838111156116155750506000910152565b60008151808452612157816020860160208601612113565b601f01601f19169290920160200192915050565b6020815260006108e4602083018461213f565b60006020828403121561219057600080fd5b81356108e481611eeb565b60008083601f8401126121ad57600080fd5b5081356001600160401b038111156121c457600080fd5b60208301915083602082850101111561140457600080fd5b600080600080600080608087890312156121f557600080fd5b6121fe87611f00565b955060208701356001600160401b038082111561221a57600080fd5b6122268a838b0161219b565b909750955060408901359450606089013591508082111561224657600080fd5b5061225389828a0161219b565b979a9699509497509295939492505050565b60006020828403121561227757600080fd5b6108e48261201b565b600181811c9082168061229457607f821691505b6020821081036122b457634e487b7160e01b600052602260045260246000fd5b50919050565b6000602082840312156122cc57600080fd5b81516108e481611eeb565b61ffff841681526060602082015260006122f4606083018561213f565b8281036040840152612306818561213f565b9695505050505050565b6001600160a01b0387811682528616602082015261ffff8516604082015260c0606082018190526000906123469083018661213f565b8281036080840152612358818661213f565b9150508260a0830152979650505050505050565b6001600160a01b03851681526001600160401b038416602082015260806040820181905260009061239f9083018561213f565b905082606083015295945050505050565b6001600160401b038316815260406020820152600061069a604083018461213f565b6000602082840312156123e457600080fd5b5051919050565b600084516123fd818460208901612113565b845190830190612411818360208901612113565b8451910190612424818360208801612113565b0195945050505050565b60008351612440818460208801612113565b835190830190612454818360208801612113565b01949350505050565b6000821982111561247e57634e487b7160e01b600052601160045260246000fd5b500190565b6020808252818101527f4e65787456617255696e742c2076616c7565206f7574736964652072616e6765604082015260600190565b6000602082840312156124ca57600080fd5b815180151581146108e457600080fd5b600082516124ec818460208701612113565b919091019291505056fea264697066735822122085285d5922d98e0b2fdd211a52f44749cf5daf1e0c04267e480adf0cc1de89cf64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.