Address Contract Verified
Address
0xa4F6400fd2Bd1C3C1cA1DeFad79EB3b5269f9299
Balance
0 ETH
Nonce
1
Code Size
5115 bytes
Creator
0x925f57f5...c5c3 at tx 0xc6013195...956010
Indexed Transactions
0
Contract Bytecode
5115 bytes
0x608060405260043610610108575f3560e01c8063967c0ccd11610092578063da25b72511610062578063da25b725146102df578063dc8b985014610312578063efc21e3f14610331578063f2fde38b14610345578063f9c10fa914610364575f80fd5b8063967c0ccd1461025b578063b5d2a1e91461026e578063c6328a461461028d578063cdf65f34146102c0575f80fd5b806358c2689b116100d857806358c2689b146101c45780635c975abb146101e35780635cbab4e1146102135780638456cb59146102285780638da5cb5b1461023c575f80fd5b8063091d2788146101135780631dac56d31461013c5780632c9465c6146101635780633f4ba83a146101ae575f80fd5b3661010f57005b5f80fd5b34801561011e575f80fd5b506101296203d09081565b6040519081526020015b60405180910390f35b348015610147575f80fd5b50610150600281565b60405161ffff9091168152602001610133565b34801561016e575f80fd5b506101967f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc881565b6040516001600160a01b039091168152602001610133565b3480156101b9575f80fd5b506101c2610378565b005b3480156101cf575f80fd5b506101966101de3660046110f1565b6103e4565b3480156101ee575f80fd5b5060035461020390600160a01b900460ff1681565b6040519015158152602001610133565b34801561021e575f80fd5b5061012960025481565b348015610233575f80fd5b506101c261046b565b348015610247575f80fd5b50600354610196906001600160a01b031681565b6101c261026936600461112b565b6104d4565b348015610279575f80fd5b506101c261028836600461116f565b610dcb565b348015610298575f80fd5b506101967f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa58581565b3480156102cb575f80fd5b50600154610196906001600160a01b031681565b3480156102ea575f80fd5b506101967f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d89491181565b34801561031d575f80fd5b506101c261032c366004611186565b610e36565b34801561033c575f80fd5b50610150601e81565b348015610350575f80fd5b506101c261035f366004611186565b610eca565b34801561036f575f80fd5b50610129610f8b565b6003546001600160a01b031633146103ab5760405162461bcd60e51b81526004016103a2906111b3565b60405180910390fd5b6003805460ff60a01b1916905560405133907f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa905f90a2565b5f80826040516020016103f791906111f8565b60408051601f1981840301815282825280516020918201206001546002546001600160f81b03198487015260609190911b6bffffffffffffffffffffffff19166021860152603585019190915260558085019190915282518085039091018152607590930190915281519101209392505050565b6003546001600160a01b031633146104955760405162461bcd60e51b81526004016103a2906111b3565b6003805460ff60a01b1916600160a01b17905560405133907f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258905f90a2565b6104dc61102c565b600354600160a01b900460ff16156105285760405162461bcd60e51b815260206004820152600f60248201526e10dbdb9d1c9858dd081c185d5cd959608a1b60448201526064016103a2565b5f821161056c5760405162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b60448201526064016103a2565b5f8151116105b35760405162461bcd60e51b8152602060048201526014602482015273456d70747920747769747465722068616e646c6560601b60448201526064016103a2565b5f6105bd826103e4565b90505f6105c8610f8b565b90508034101561060d5760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b60448201526064016103a2565b6040516370a0823160e01b81523060048201525f907f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc86001600160a01b0316906370a0823190602401602060405180830381865afa158015610671573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610695919061121e565b6040516323b872dd60e01b8152336004820152306024820152604481018790529091507f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc86001600160a01b0316906323b872dd906064016020604051808303815f875af1158015610708573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061072c9190611235565b61076a5760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016103a2565b6040516370a0823160e01b81523060048201525f907f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc86001600160a01b0316906370a0823190602401602060405180830381865afa1580156107ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107f2919061121e565b90505f6107ff8383611254565b9050868110156108515760405162461bcd60e51b815260206004820152601860248201527f5472616e7366657220616d6f756e74206d69736d61746368000000000000000060448201526064016103a2565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa58581166004830152602482018990527f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc8169063095ea7b3906044016020604051808303815f875af11580156108dd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109019190611235565b61093f5760405162461bcd60e51b815260206004820152600f60248201526e105c1c1c9bdd985b0819985a5b1959608a1b60448201526064016103a2565b60405162f5287b60e41b81526001600160a01b037f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc88116600483015260248201899052601e604483015286811660648301525f6084830181905260a48301819052917f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa58590911690630f5287b09060c4016020604051808303815f875af11580156109eb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a0f9190611279565b6040516370a0823160e01b81523060048201529091505f906001600160a01b037f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc816906370a0823190602401602060405180830381865afa158015610a76573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a9a919061121e565b9050610aa68985611254565b811115610af55760405162461bcd60e51b815260206004820152601d60248201527f42726964676520646964206e6f74207265636569766520746f6b656e7300000060448201526064016103a2565b84811015610b455760405162461bcd60e51b815260206004820152601b60248201527f556e65787065637465642062616c616e6365206465637265617365000000000060448201526064016103a2565b60405163095ea7b360e01b81526001600160a01b037f0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585811660048301525f60248301527f0000000000000000000000000f7dc5d02cc1e1f5ee47854d534d332a1081ccc8169063095ea7b3906044016020604051808303815f875af1158015610bd0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bf49190611235565b505f3389898c86604051602001610c0f9594939291906112cb565b60408051601f19818403018152908290526001546312d729bd60e21b83529092505f916001600160a01b037f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911811692634b5ca6f4928c92610c8692601e92911690889088906203d090906002903390600401611312565b60206040518083038185885af1158015610ca2573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610cc79190611279565b9050886001600160a01b0316336001600160a01b03167f760345242447126ab56a8a34e3e51a46ea62b99ac50ce7f3aa0ebe6258bab5f98c8e8886604051610d12949392919061136a565b60405180910390a35f610d258934611254565b90508015610db4576040515f90339083908381818185875af1925050503d805f8114610d6c576040519150601f19603f3d011682016040523d82523d5f602084013e610d71565b606091505b5050905080610db25760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016103a2565b505b50505050505050505050610dc760015f55565b5050565b6003546001600160a01b03163314610df55760405162461bcd60e51b81526004016103a2906111b3565b80610e315760405162461bcd60e51b815260206004820152600c60248201526b092dcecc2d8d2c840d0c2e6d60a31b60448201526064016103a2565b600255565b6003546001600160a01b03163314610e605760405162461bcd60e51b81526004016103a2906111b3565b6001600160a01b038116610ea85760405162461bcd60e51b815260206004820152600f60248201526e496e76616c696420666163746f727960881b60448201526064016103a2565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6003546001600160a01b03163314610ef45760405162461bcd60e51b81526004016103a2906111b3565b6001600160a01b038116610f3a5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21037bbb732b960991b60448201526064016103a2565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b60405163c23ee3c360e01b8152601e60048201525f602482018190526203d09060448301529081906001600160a01b037f00000000000000000000000027428dd2d3dd32a4d7f7c497eaaa23130d894911169063c23ee3c3906064016040805180830381865afa158015611001573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061102591906113a3565b5092915050565b60025f540361104e57604051633ee5aeb560e01b815260040160405180910390fd5b60025f55565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112611077575f80fd5b813567ffffffffffffffff8082111561109257611092611054565b604051601f8301601f19908116603f011681019082821181831017156110ba576110ba611054565b816040528381528660208588010111156110d2575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f60208284031215611101575f80fd5b813567ffffffffffffffff811115611117575f80fd5b61112384828501611068565b949350505050565b5f806040838503121561113c575f80fd5b82359150602083013567ffffffffffffffff811115611159575f80fd5b61116585828601611068565b9150509250929050565b5f6020828403121561117f575f80fd5b5035919050565b5f60208284031215611196575f80fd5b81356001600160a01b03811681146111ac575f80fd5b9392505050565b6020808252600990820152682737ba1037bbb732b960b91b604082015260600190565b5f5b838110156111f05781810151838201526020016111d8565b50505f910152565b5f82516112098184602087016111d6565b625f763360e81b920191825250600301919050565b5f6020828403121561122e575f80fd5b5051919050565b5f60208284031215611245575f80fd5b815180151581146111ac575f80fd5b8181038181111561127357634e487b7160e01b5f52601160045260245ffd5b92915050565b5f60208284031215611289575f80fd5b815167ffffffffffffffff811681146111ac575f80fd5b5f81518084526112b78160208601602086016111d6565b601f01601f19169290920160200192915050565b5f60018060a01b03808816835260a060208401526112ec60a08401886112a0565b9516604083015250606081019290925267ffffffffffffffff1660809091015292915050565b5f61ffff808a16835260018060a01b03808a16602085015260e0604085015261133e60e085018a6112a0565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b608081525f61137c60808301876112a0565b60208301959095525067ffffffffffffffff92831660408201529116606090910152919050565b5f80604083850312156113b4575f80fd5b50508051602090910151909290915056fea2646970667358221220c75b5358fd0e3ca07381012f7539f38c8de9b8ea0fc988723418e48323e198d164736f6c63430008140033
Verified Source Code Full Match
Compiler: v0.8.20+commit.a1b79de6
EVM: shanghai
Optimization: Yes (200 runs)
DepositBridge.sol 234 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import "../interfaces/IWormholeRelayer.sol";
import "../interfaces/ITokenBridge.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
/**
* @title DepositBridge
* @notice Bridge ZEUS from Ethereum to Base in 1 TX with Wormhole Auto-Relay
* @dev Uses separate TokenBridge.transferTokens() + WormholeRelayer.sendPayloadToEvm()
* because transferTokensWithPayload() doesn't support automatic relay
*/
contract DepositBridge is ReentrancyGuard {
IERC20 public immutable zeusToken;
ITokenBridge public immutable tokenBridge;
IWormholeRelayer public immutable wormholeRelayer;
uint16 public constant BASE_CHAIN_ID = 30; // Wormhole chain ID for Base
uint16 public constant ETHEREUM_CHAIN_ID = 2; // Wormhole chain ID for Ethereum
uint256 public constant GAS_LIMIT = 250_000; // Gas for receiving on Base
address public walletFactoryOnBase; // WalletFactory contract address on Base
bytes32 public userWalletBytecodeHash; // Hash of UserWallet bytecode for CREATE2 computation
address public owner;
bool public paused = false;
event DepositInitiated(
address indexed user,
string twitterHandle,
address indexed recipientWallet,
uint256 amount,
uint64 tokenSequence,
uint64 messageSequence
);
event Paused(address indexed by);
event Unpaused(address indexed by);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(
address _zeusToken,
address _wormholeRelayer,
address _tokenBridge,
address _walletFactoryOnBase,
bytes32 _userWalletBytecodeHash
) {
require(_zeusToken != address(0), "Invalid token");
require(_wormholeRelayer != address(0), "Invalid relayer");
require(_tokenBridge != address(0), "Invalid bridge");
require(_walletFactoryOnBase != address(0), "Invalid factory");
require(_userWalletBytecodeHash != bytes32(0), "Invalid bytecode hash");
zeusToken = IERC20(_zeusToken);
wormholeRelayer = IWormholeRelayer(_wormholeRelayer);
tokenBridge = ITokenBridge(_tokenBridge);
walletFactoryOnBase = _walletFactoryOnBase;
userWalletBytecodeHash = _userWalletBytecodeHash;
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
modifier whenNotPaused() {
require(!paused, "Contract paused");
_;
}
/**
* @notice Emergency pause
*/
function pause() external onlyOwner {
paused = true;
emit Paused(msg.sender);
}
function unpause() external onlyOwner {
paused = false;
emit Unpaused(msg.sender);
}
/**
* @notice Compute deterministic UserWallet address on Base (same as WalletFactory.computeAddress)
* @param twitterHandle Twitter handle (without @)
* @return Predicted UserWallet address on Base
*/
function computeUserWalletAddress(string memory twitterHandle)
public
view
returns (address)
{
// V3: Add "_v3" suffix to match WalletFactory V3 on Base
bytes32 salt = keccak256(abi.encodePacked(twitterHandle, "_v3"));
bytes32 hash = keccak256(
abi.encodePacked(
bytes1(0xff),
walletFactoryOnBase,
salt,
userWalletBytecodeHash
)
);
return address(uint160(uint256(hash)));
}
/**
* @notice Quote cost for bridge (only WormholeRelayer fee, TokenBridge is free)
*/
function quoteCrossChainDeposit() public view returns (uint256 cost) {
(uint256 deliveryCost, ) = wormholeRelayer.quoteEVMDeliveryPrice(
BASE_CHAIN_ID,
0,
GAS_LIMIT
);
return deliveryCost;
}
/**
* @notice Deposit and bridge to Base in 1 TX
* @param amount Amount of ZEUS tokens
* @param twitterHandle Twitter handle of recipient (without @)
* @dev Computes UserWallet address deterministically and sends tokens directly
* UserWallet doesn't need to be deployed yet - tokens will arrive when it's deployed
*/
function depositAndBridge(
uint256 amount,
string memory twitterHandle
) external payable nonReentrant whenNotPaused {
require(amount > 0, "Amount must be > 0");
require(bytes(twitterHandle).length > 0, "Empty twitter handle");
// Compute deterministic UserWallet address (may not be deployed yet)
address recipientWallet = computeUserWalletAddress(twitterHandle);
uint256 cost = quoteCrossChainDeposit();
require(msg.value >= cost, "Insufficient fee");
// Transfer ZEUS from user
uint256 balanceBefore = zeusToken.balanceOf(address(this));
require(zeusToken.transferFrom(msg.sender, address(this), amount), "Transfer failed");
// Verify actual amount received (handles fee-on-transfer tokens)
uint256 balanceAfter = zeusToken.balanceOf(address(this));
uint256 actualAmount = balanceAfter - balanceBefore;
require(actualAmount >= amount, "Transfer amount mismatch");
// 1. Send tokens via TokenBridge directly to UserWallet on Base
// Note: Wallet doesn't need to be deployed yet - tokens will arrive when it's deployed
require(zeusToken.approve(address(tokenBridge), amount), "Approval failed");
uint64 tokenSequence = tokenBridge.transferTokens(
address(zeusToken),
amount,
BASE_CHAIN_ID,
bytes32(uint256(uint160(recipientWallet))), // Send to computed UserWallet address
0, // arbiter fee
0 // nonce
);
// Security: Verify tokens were actually transferred to bridge
// Use range checks instead of strict equality to handle edge cases
uint256 balanceAfterBridge = zeusToken.balanceOf(address(this));
require(balanceAfterBridge <= balanceAfter - amount, "Bridge did not receive tokens");
require(balanceAfterBridge >= balanceBefore, "Unexpected balance decrease");
// Security: Reset approval to 0 (defense in depth)
zeusToken.approve(address(tokenBridge), 0);
// 2. Send message via WormholeRelayer (with automatic relay)
// Note: We send twitterHandle instead of just address for better tracking
bytes memory payload = abi.encode(
msg.sender, // original sender on Ethereum
twitterHandle, // twitter handle of recipient
recipientWallet, // computed UserWallet address on Base
amount, // amount being sent
tokenSequence // token transfer sequence number for matching
);
uint64 messageSequence = wormholeRelayer.sendPayloadToEvm{value: cost}(
BASE_CHAIN_ID,
walletFactoryOnBase,
payload,
0, // no receiver value
GAS_LIMIT,
ETHEREUM_CHAIN_ID, // refund chain
msg.sender // refund address (original sender)
);
emit DepositInitiated(msg.sender, twitterHandle, recipientWallet, amount, tokenSequence, messageSequence);
// Refund excess ETH
uint256 excess = msg.value - cost;
if (excess > 0) {
(bool success, ) = msg.sender.call{value: excess}("");
require(success, "Refund failed");
}
}
/**
* @notice Update WalletFactory address on Base
*/
function setWalletFactoryOnBase(address _factory) external onlyOwner {
require(_factory != address(0), "Invalid factory");
walletFactoryOnBase = _factory;
}
/**
* @notice Update UserWallet bytecode hash (if UserWallet contract changes)
*/
function setUserWalletBytecodeHash(bytes32 _hash) external onlyOwner {
require(_hash != bytes32(0), "Invalid hash");
userWalletBytecodeHash = _hash;
}
/**
* @notice Transfer ownership
*/
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "Invalid owner");
address oldOwner = owner;
owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @notice Receive ETH
*/
receive() external payable {}
}
IWormholeRelayer.sol 35 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IWormholeRelayer
* @notice Interface for Wormhole Automatic Relayer
* @dev Used for cross-chain message delivery with automatic relay
*/
interface IWormholeRelayer {
function quoteEVMDeliveryPrice(
uint16 targetChain,
uint256 receiverValue,
uint256 gasLimit
) external view returns (uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused);
// Simple version (refunds go to delivery provider)
function sendPayloadToEvm(
uint16 targetChain,
address targetAddress,
bytes memory payload,
uint256 receiverValue,
uint256 gasLimit
) external payable returns (uint64 sequence);
// Full version with refund parameters (REQUIRED for production)
function sendPayloadToEvm(
uint16 targetChain,
address targetAddress,
bytes memory payload,
uint256 receiverValue,
uint256 gasLimit,
uint16 refundChain,
address refundAddress
) external payable returns (uint64 sequence);
}
ITokenBridge.sol 42 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title ITokenBridge
* @notice Interface for Wormhole Token Bridge
*/
interface ITokenBridge {
struct Transfer {
uint8 payloadID;
uint256 amount;
bytes32 tokenAddress;
uint16 tokenChain;
bytes32 to;
uint16 toChain;
uint256 fee;
}
function transferTokens(
address token,
uint256 amount,
uint16 recipientChain,
bytes32 recipient,
uint256 arbiterFee,
uint32 nonce
) external payable returns (uint64 sequence);
function transferTokensWithPayload(
address token,
uint256 amount,
uint16 toChain,
bytes32 to,
uint32 batchID,
bytes memory payload
) external payable returns (uint64 sequence);
function completeTransfer(bytes memory encodedVaa) external returns (bytes memory);
function completeTransferWithPayload(bytes memory encodedVaa) external returns (bytes memory);
function parseTransfer(bytes memory encodedVaa) external pure returns (Transfer memory transfer);
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
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 value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
Read Contract
BASE_CHAIN_ID 0xefc21e3f → uint16
ETHEREUM_CHAIN_ID 0x1dac56d3 → uint16
GAS_LIMIT 0x091d2788 → uint256
computeUserWalletAddress 0x58c2689b → address
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
quoteCrossChainDeposit 0xf9c10fa9 → uint256
tokenBridge 0xc6328a46 → address
userWalletBytecodeHash 0x5cbab4e1 → bytes32
walletFactoryOnBase 0xcdf65f34 → address
wormholeRelayer 0xda25b725 → address
zeusToken 0x2c9465c6 → address
Write Contract 6 functions
These functions modify contract state and require a wallet transaction to execute.
depositAndBridge 0x967c0ccd
uint256 amount
string twitterHandle
pause 0x8456cb59
No parameters
setUserWalletBytecodeHash 0xb5d2a1e9
bytes32 _hash
setWalletFactoryOnBase 0xdc8b9850
address _factory
transferOwnership 0xf2fde38b
address newOwner
unpause 0x3f4ba83a
No parameters
Recent Transactions
No transactions found for this address