ETH Price: $1,782.97 (+10.11%)

Contract

0xB09F16F625B363875e39ADa56C03682088471523
Transaction Hash
Method
Block
From
To
Donate And Claim2252658442024-06-24 15:38:01302 days ago1719243481IN
LayerZero Foundation: Proof of Donation Claim 1
1.38888888 ETH0.00000150.01
Donate And Claim2240439782024-06-21 2:47:49306 days ago1718938069IN
LayerZero Foundation: Proof of Donation Claim 1
1.1731 ETH0.00000150.01
Donate And Claim2238598972024-06-20 14:03:07306 days ago1718892187IN
LayerZero Foundation: Proof of Donation Claim 1
1.11581512 ETH0.000520453.434536
Donate And Claim2238163142024-06-20 11:03:54306 days ago1718881434IN
LayerZero Foundation: Proof of Donation Claim 1
2.83523635 ETH0.000030550.194729
VIEW ADVANCED FILTER

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
2704816192024-11-03 4:12:58171 days ago1730607178
LayerZero Foundation: Proof of Donation Claim 1
0.00051 ETH
2685208902024-10-28 11:24:52176 days ago1730114692
LayerZero Foundation: Proof of Donation Claim 1
0.00045779 ETH
2676689092024-10-25 23:51:45179 days ago1729900305
LayerZero Foundation: Proof of Donation Claim 1
0.00047503 ETH
2675216082024-10-25 13:34:33179 days ago1729863273
LayerZero Foundation: Proof of Donation Claim 1
0.00152 ETH
2672711832024-10-24 20:07:02180 days ago1729800422
LayerZero Foundation: Proof of Donation Claim 1
0.00061131 ETH
2671750732024-10-24 13:24:42180 days ago1729776282
LayerZero Foundation: Proof of Donation Claim 1
0.0002 ETH
2671748612024-10-24 13:23:48180 days ago1729776228
LayerZero Foundation: Proof of Donation Claim 1
0.0002 ETH
2671747782024-10-24 13:23:27180 days ago1729776207
LayerZero Foundation: Proof of Donation Claim 1
0.00019761 ETH
2669038082024-10-23 18:29:54181 days ago1729708194
LayerZero Foundation: Proof of Donation Claim 1
0.0018 ETH
2668131512024-10-23 12:09:33181 days ago1729685373
LayerZero Foundation: Proof of Donation Claim 1
0.00817848 ETH
2668126032024-10-23 12:07:16181 days ago1729685236
LayerZero Foundation: Proof of Donation Claim 1
0.00827848 ETH
2668120862024-10-23 12:05:04181 days ago1729685104
LayerZero Foundation: Proof of Donation Claim 1
0.00002151 ETH
2668120862024-10-23 12:05:04181 days ago1729685104
LayerZero Foundation: Proof of Donation Claim 1
0.00817848 ETH
2668119572024-10-23 12:04:33181 days ago1729685073
LayerZero Foundation: Proof of Donation Claim 1
0.00002151 ETH
2668119572024-10-23 12:04:33181 days ago1729685073
LayerZero Foundation: Proof of Donation Claim 1
0.00817848 ETH
2668083292024-10-23 11:49:25181 days ago1729684165
LayerZero Foundation: Proof of Donation Claim 1
0.0082 ETH
2667301032024-10-23 6:22:05182 days ago1729664525
LayerZero Foundation: Proof of Donation Claim 1
0.00205763 ETH
2667301032024-10-23 6:22:05182 days ago1729664525
LayerZero Foundation: Proof of Donation Claim 1
0.00081736 ETH
2664779342024-10-22 12:45:19182 days ago1729601119
LayerZero Foundation: Proof of Donation Claim 1
0.0048 ETH
2664724472024-10-22 12:22:25182 days ago1729599745
LayerZero Foundation: Proof of Donation Claim 1
0.0048 ETH
2664263312024-10-22 9:09:36182 days ago1729588176
LayerZero Foundation: Proof of Donation Claim 1
0.00108472 ETH
2661918242024-10-21 16:47:52183 days ago1729529272
LayerZero Foundation: Proof of Donation Claim 1
0.00028799 ETH
2661917042024-10-21 16:47:22183 days ago1729529242
LayerZero Foundation: Proof of Donation Claim 1
0.00027625 ETH
2661915182024-10-21 16:46:35183 days ago1729529195
LayerZero Foundation: Proof of Donation Claim 1
0.00030445 ETH
2661914182024-10-21 16:46:11183 days ago1729529171
LayerZero Foundation: Proof of Donation Claim 1
0.00030398 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DonateAndClaim

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, MIT license
File 1 of 18 : DonateAndClaim.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.22;

import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import { MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";

import { IOFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/interfaces/IOFT.sol";

import { IDonate, Currency } from "./donate/IDonate.sol";
import { IClaim } from "./claim/IClaim.sol";

/**
 * @title DonateAndClaim
 */
contract DonateAndClaim {
    using SafeERC20 for IERC20;

    address public immutable donateContract;
    address public immutable claimContract;

    // stargate instances that will be used to move donations in the event this is inherited by the DonateRemote.sol
    address public immutable stargateUsdc;
    address public immutable stargateUsdt;
    address public immutable stargateNative;

    IERC20 public immutable tokenUsdc;
    IERC20 public immutable tokenUsdt;

    // We pass stargate to ensure there is no config mismatch with regards to stargate and corresponding token address
    constructor(
        address _donateContract,
        address _claimContract,
        address _stargateUsdc,
        address _stargateUsdt,
        address _stargateNative
    ) {
        donateContract = _donateContract;
        claimContract = _claimContract;

        if (_stargateUsdc != address(0)) {
            stargateUsdc = _stargateUsdc;
            tokenUsdc = IERC20(IOFT(stargateUsdc).token());
            tokenUsdc.forceApprove(donateContract, type(uint256).max);
        }

        if (_stargateUsdt != address(0)) {
            stargateUsdt = _stargateUsdt;
            tokenUsdt = IERC20(IOFT(stargateUsdt).token());
            tokenUsdt.forceApprove(donateContract, type(uint256).max);
        }

        // There is no token for native because donations are only accepted in native, eg. NOT 'WETH'
        if (_stargateNative != address(0)) {
            stargateNative = _stargateNative;
            // Only accept stargate if it is the native token
            if (IOFT(stargateNative).token() != address(0)) {
                revert IDonate.InvalidNativeStargate();
            }
        }
    }

    function donateAndClaim(
        Currency currency,
        uint256 amountToDonate,
        uint256 _zroAmount,
        bytes32[] calldata _proof,
        address _to,
        bytes calldata _extraBytes
    ) external payable returns (MessagingReceipt memory receipt) {
        uint256 donateNativeAmount;
        uint256 msgFee;

        // move tokens into the wrapper to forward to the donate contract
        if (currency == Currency.USDC && stargateUsdc != address(0)) {
            tokenUsdc.safeTransferFrom(msg.sender, address(this), amountToDonate);

            // donateNativeAmount = 0;
            msgFee = msg.value;
        } else if (currency == Currency.USDT && stargateUsdt != address(0)) {
            tokenUsdt.safeTransferFrom(msg.sender, address(this), amountToDonate);

            // donateNativeAmount = 0;
            msgFee = msg.value;
        } else if (currency == Currency.Native && stargateNative != address(0)) {
            if (msg.value < amountToDonate) revert IDonate.InsufficientMsgValue();

            donateNativeAmount = amountToDonate;
            msgFee = msg.value - donateNativeAmount;
        } else {
            // sanity just in case somehow a different currency is somehow passed
            revert IDonate.UnsupportedCurrency(currency);
        }

        // donate
        IDonate(donateContract).donate{ value: donateNativeAmount }(currency, amountToDonate, msg.sender);

        // claim
        return IClaim(claimContract).claim{ value: msgFee }(msg.sender, currency, _zroAmount, _proof, _to, _extraBytes);
    }
}

File 2 of 18 : IOAppCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { ILayerZeroEndpointV2 } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";

/**
 * @title IOAppCore
 */
interface IOAppCore {
    // Custom error messages
    error OnlyPeer(uint32 eid, bytes32 sender);
    error NoPeer(uint32 eid);
    error InvalidEndpointCall();
    error InvalidDelegate();

    // Event emitted when a peer (OApp) is set for a corresponding endpoint
    event PeerSet(uint32 eid, bytes32 peer);

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol contract.
     * @return receiverVersion The version of the OAppReceiver.sol contract.
     */
    function oAppVersion() external view returns (uint64 senderVersion, uint64 receiverVersion);

    /**
     * @notice Retrieves the LayerZero endpoint associated with the OApp.
     * @return iEndpoint The LayerZero endpoint as an interface.
     */
    function endpoint() external view returns (ILayerZeroEndpointV2 iEndpoint);

    /**
     * @notice Retrieves the peer (OApp) associated with a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @return peer The peer address (OApp instance) associated with the corresponding endpoint.
     */
    function peers(uint32 _eid) external view returns (bytes32 peer);

    /**
     * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @param _peer The address of the peer to be associated with the corresponding endpoint.
     */
    function setPeer(uint32 _eid, bytes32 _peer) external;

    /**
     * @notice Sets the delegate address for the OApp Core.
     * @param _delegate The address of the delegate to be set.
     */
    function setDelegate(address _delegate) external;
}

File 3 of 18 : OAppCore.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { IOAppCore, ILayerZeroEndpointV2 } from "./interfaces/IOAppCore.sol";

/**
 * @title OAppCore
 * @dev Abstract contract implementing the IOAppCore interface with basic OApp configurations.
 */
abstract contract OAppCore is IOAppCore, Ownable {
    // The LayerZero endpoint associated with the given OApp
    ILayerZeroEndpointV2 public immutable endpoint;

    // Mapping to store peers associated with corresponding endpoints
    mapping(uint32 eid => bytes32 peer) public peers;

    /**
     * @dev Constructor to initialize the OAppCore with the provided endpoint and delegate.
     * @param _endpoint The address of the LOCAL Layer Zero endpoint.
     * @param _delegate The delegate capable of making OApp configurations inside of the endpoint.
     *
     * @dev The delegate typically should be set as the owner of the contract.
     */
    constructor(address _endpoint, address _delegate) {
        endpoint = ILayerZeroEndpointV2(_endpoint);

        if (_delegate == address(0)) revert InvalidDelegate();
        endpoint.setDelegate(_delegate);
    }

    /**
     * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @param _peer The address of the peer to be associated with the corresponding endpoint.
     *
     * @dev Only the owner/admin of the OApp can call this function.
     * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.
     * @dev Set this to bytes32(0) to remove the peer address.
     * @dev Peer is a bytes32 to accommodate non-evm chains.
     */
    function setPeer(uint32 _eid, bytes32 _peer) public virtual onlyOwner {
        _setPeer(_eid, _peer);
    }

    /**
     * @notice Sets the peer address (OApp instance) for a corresponding endpoint.
     * @param _eid The endpoint ID.
     * @param _peer The address of the peer to be associated with the corresponding endpoint.
     *
     * @dev Indicates that the peer is trusted to send LayerZero messages to this OApp.
     * @dev Set this to bytes32(0) to remove the peer address.
     * @dev Peer is a bytes32 to accommodate non-evm chains.
     */
    function _setPeer(uint32 _eid, bytes32 _peer) internal virtual {
        peers[_eid] = _peer;
        emit PeerSet(_eid, _peer);
    }

    /**
     * @notice Internal function to get the peer address associated with a specific endpoint; reverts if NOT set.
     * ie. the peer is set to bytes32(0).
     * @param _eid The endpoint ID.
     * @return peer The address of the peer associated with the specified endpoint.
     */
    function _getPeerOrRevert(uint32 _eid) internal view virtual returns (bytes32) {
        bytes32 peer = peers[_eid];
        if (peer == bytes32(0)) revert NoPeer(_eid);
        return peer;
    }

    /**
     * @notice Sets the delegate address for the OApp.
     * @param _delegate The address of the delegate to be set.
     *
     * @dev Only the owner/admin of the OApp can call this function.
     * @dev Provides the ability for a delegate to set configs, on behalf of the OApp, directly on the Endpoint contract.
     */
    function setDelegate(address _delegate) public onlyOwner {
        endpoint.setDelegate(_delegate);
    }
}

File 4 of 18 : OAppSender.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { MessagingParams, MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";
import { OAppCore } from "./OAppCore.sol";

/**
 * @title OAppSender
 * @dev Abstract contract implementing the OAppSender functionality for sending messages to a LayerZero endpoint.
 */
abstract contract OAppSender is OAppCore {
    using SafeERC20 for IERC20;

    // Custom error messages
    error NotEnoughNative(uint256 msgValue);
    error LzTokenUnavailable();

    // @dev The version of the OAppSender implementation.
    // @dev Version is bumped when changes are made to this contract.
    uint64 internal constant SENDER_VERSION = 1;

    /**
     * @notice Retrieves the OApp version information.
     * @return senderVersion The version of the OAppSender.sol contract.
     * @return receiverVersion The version of the OAppReceiver.sol contract.
     *
     * @dev Providing 0 as the default for OAppReceiver version. Indicates that the OAppReceiver is not implemented.
     * ie. this is a SEND only OApp.
     * @dev If the OApp uses both OAppSender and OAppReceiver, then this needs to be override returning the correct versions
     */
    function oAppVersion() public view virtual returns (uint64 senderVersion, uint64 receiverVersion) {
        return (SENDER_VERSION, 0);
    }

    /**
     * @dev Internal function to interact with the LayerZero EndpointV2.quote() for fee calculation.
     * @param _dstEid The destination endpoint ID.
     * @param _message The message payload.
     * @param _options Additional options for the message.
     * @param _payInLzToken Flag indicating whether to pay the fee in LZ tokens.
     * @return fee The calculated MessagingFee for the message.
     *      - nativeFee: The native fee for the message.
     *      - lzTokenFee: The LZ token fee for the message.
     */
    function _quote(
        uint32 _dstEid,
        bytes memory _message,
        bytes memory _options,
        bool _payInLzToken
    ) internal view virtual returns (MessagingFee memory fee) {
        return
            endpoint.quote(
                MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _payInLzToken),
                address(this)
            );
    }

    /**
     * @dev Internal function to interact with the LayerZero EndpointV2.send() for sending a message.
     * @param _dstEid The destination endpoint ID.
     * @param _message The message payload.
     * @param _options Additional options for the message.
     * @param _fee The calculated LayerZero fee for the message.
     *      - nativeFee: The native fee.
     *      - lzTokenFee: The lzToken fee.
     * @param _refundAddress The address to receive any excess fee values sent to the endpoint.
     * @return receipt The receipt for the sent message.
     *      - guid: The unique identifier for the sent message.
     *      - nonce: The nonce of the sent message.
     *      - fee: The LayerZero fee incurred for the message.
     */
    function _lzSend(
        uint32 _dstEid,
        bytes memory _message,
        bytes memory _options,
        MessagingFee memory _fee,
        address _refundAddress
    ) internal virtual returns (MessagingReceipt memory receipt) {
        // @dev Push corresponding fees to the endpoint, any excess is sent back to the _refundAddress from the endpoint.
        uint256 messageValue = _payNative(_fee.nativeFee);
        if (_fee.lzTokenFee > 0) _payLzToken(_fee.lzTokenFee);

        return
            // solhint-disable-next-line check-send-result
            endpoint.send{ value: messageValue }(
                MessagingParams(_dstEid, _getPeerOrRevert(_dstEid), _message, _options, _fee.lzTokenFee > 0),
                _refundAddress
            );
    }

    /**
     * @dev Internal function to pay the native fee associated with the message.
     * @param _nativeFee The native fee to be paid.
     * @return nativeFee The amount of native currency paid.
     *
     * @dev If the OApp needs to initiate MULTIPLE LayerZero messages in a single transaction,
     * this will need to be overridden because msg.value would contain multiple lzFees.
     * @dev Should be overridden in the event the LayerZero endpoint requires a different native currency.
     * @dev Some EVMs use an ERC20 as a method for paying transactions/gasFees.
     * @dev The endpoint is EITHER/OR, ie. it will NOT support both types of native payment at a time.
     */
    function _payNative(uint256 _nativeFee) internal virtual returns (uint256 nativeFee) {
        if (msg.value != _nativeFee) revert NotEnoughNative(msg.value);
        return _nativeFee;
    }

    /**
     * @dev Internal function to pay the LZ token fee associated with the message.
     * @param _lzTokenFee The LZ token fee to be paid.
     *
     * @dev If the caller is trying to pay in the specified lzToken, then the lzTokenFee is passed to the endpoint.
     * @dev Any excess sent, is passed back to the specified _refundAddress in the _lzSend().
     */
    function _payLzToken(uint256 _lzTokenFee) internal virtual {
        // @dev Cannot cache the token because it is not immutable in the endpoint.
        address lzToken = endpoint.lzToken();
        if (lzToken == address(0)) revert LzTokenUnavailable();

        // Pay LZ token fee by sending tokens to the endpoint.
        IERC20(lzToken).safeTransferFrom(msg.sender, address(endpoint), _lzTokenFee);
    }
}

File 5 of 18 : IOFT.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { MessagingReceipt, MessagingFee } from "../../oapp/OAppSender.sol";

/**
 * @dev Struct representing token parameters for the OFT send() operation.
 */
struct SendParam {
    uint32 dstEid; // Destination endpoint ID.
    bytes32 to; // Recipient address.
    uint256 amountLD; // Amount to send in local decimals.
    uint256 minAmountLD; // Minimum amount to send in local decimals.
    bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message.
    bytes composeMsg; // The composed message for the send() operation.
    bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations.
}

/**
 * @dev Struct representing OFT limit information.
 * @dev These amounts can change dynamically and are up the the specific oft implementation.
 */
struct OFTLimit {
    uint256 minAmountLD; // Minimum amount in local decimals that can be sent to the recipient.
    uint256 maxAmountLD; // Maximum amount in local decimals that can be sent to the recipient.
}

/**
 * @dev Struct representing OFT receipt information.
 */
struct OFTReceipt {
    uint256 amountSentLD; // Amount of tokens ACTUALLY debited from the sender in local decimals.
    // @dev In non-default implementations, the amountReceivedLD COULD differ from this value.
    uint256 amountReceivedLD; // Amount of tokens to be received on the remote side.
}

/**
 * @dev Struct representing OFT fee details.
 * @dev Future proof mechanism to provide a standardized way to communicate fees to things like a UI.
 */
struct OFTFeeDetail {
    int256 feeAmountLD; // Amount of the fee in local decimals.
    string description; // Description of the fee.
}

/**
 * @title IOFT
 * @dev Interface for the OftChain (OFT) token.
 * @dev Does not inherit ERC20 to accommodate usage by OFTAdapter as well.
 * @dev This specific interface ID is '0x02e49c2c'.
 */
interface IOFT {
    // Custom error messages
    error InvalidLocalDecimals();
    error SlippageExceeded(uint256 amountLD, uint256 minAmountLD);

    // Events
    event OFTSent(
        bytes32 indexed guid, // GUID of the OFT message.
        uint32 dstEid, // Destination Endpoint ID.
        address indexed fromAddress, // Address of the sender on the src chain.
        uint256 amountSentLD, // Amount of tokens sent in local decimals.
        uint256 amountReceivedLD // Amount of tokens received in local decimals.
    );
    event OFTReceived(
        bytes32 indexed guid, // GUID of the OFT message.
        uint32 srcEid, // Source Endpoint ID.
        address indexed toAddress, // Address of the recipient on the dst chain.
        uint256 amountReceivedLD // Amount of tokens received in local decimals.
    );

    /**
     * @notice Retrieves interfaceID and the version of the OFT.
     * @return interfaceId The interface ID.
     * @return version The version.
     *
     * @dev interfaceId: This specific interface ID is '0x02e49c2c'.
     * @dev version: Indicates a cross-chain compatible msg encoding with other OFTs.
     * @dev If a new feature is added to the OFT cross-chain msg encoding, the version will be incremented.
     * ie. localOFT version(x,1) CAN send messages to remoteOFT version(x,1)
     */
    function oftVersion() external view returns (bytes4 interfaceId, uint64 version);

    /**
     * @notice Retrieves the address of the token associated with the OFT.
     * @return token The address of the ERC20 token implementation.
     */
    function token() external view returns (address);

    /**
     * @notice Indicates whether the OFT contract requires approval of the 'token()' to send.
     * @return requiresApproval Needs approval of the underlying token implementation.
     *
     * @dev Allows things like wallet implementers to determine integration requirements,
     * without understanding the underlying token implementation.
     */
    function approvalRequired() external view returns (bool);

    /**
     * @notice Retrieves the shared decimals of the OFT.
     * @return sharedDecimals The shared decimals of the OFT.
     */
    function sharedDecimals() external view returns (uint8);

    /**
     * @notice Provides a quote for OFT-related operations.
     * @param _sendParam The parameters for the send operation.
     * @return limit The OFT limit information.
     * @return oftFeeDetails The details of OFT fees.
     * @return receipt The OFT receipt information.
     */
    function quoteOFT(
        SendParam calldata _sendParam
    ) external view returns (OFTLimit memory, OFTFeeDetail[] memory oftFeeDetails, OFTReceipt memory);

    /**
     * @notice Provides a quote for the send() operation.
     * @param _sendParam The parameters for the send() operation.
     * @param _payInLzToken Flag indicating whether the caller is paying in the LZ token.
     * @return fee The calculated LayerZero messaging fee from the send() operation.
     *
     * @dev MessagingFee: LayerZero msg fee
     *  - nativeFee: The native fee.
     *  - lzTokenFee: The lzToken fee.
     */
    function quoteSend(SendParam calldata _sendParam, bool _payInLzToken) external view returns (MessagingFee memory);

    /**
     * @notice Executes the send() operation.
     * @param _sendParam The parameters for the send operation.
     * @param _fee The fee information supplied by the caller.
     *      - nativeFee: The native fee.
     *      - lzTokenFee: The lzToken fee.
     * @param _refundAddress The address to receive any excess funds from fees etc. on the src.
     * @return receipt The LayerZero messaging receipt from the send() operation.
     * @return oftReceipt The OFT receipt information.
     *
     * @dev MessagingReceipt: LayerZero msg receipt
     *  - guid: The unique identifier for the sent message.
     *  - nonce: The nonce of the sent message.
     *  - fee: The LayerZero fee incurred for the message.
     */
    function send(
        SendParam calldata _sendParam,
        MessagingFee calldata _fee,
        address _refundAddress
    ) external payable returns (MessagingReceipt memory, OFTReceipt memory);
}

File 6 of 18 : ILayerZeroEndpointV2.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

import { IMessageLibManager } from "./IMessageLibManager.sol";
import { IMessagingComposer } from "./IMessagingComposer.sol";
import { IMessagingChannel } from "./IMessagingChannel.sol";
import { IMessagingContext } from "./IMessagingContext.sol";

struct MessagingParams {
    uint32 dstEid;
    bytes32 receiver;
    bytes message;
    bytes options;
    bool payInLzToken;
}

struct MessagingReceipt {
    bytes32 guid;
    uint64 nonce;
    MessagingFee fee;
}

struct MessagingFee {
    uint256 nativeFee;
    uint256 lzTokenFee;
}

struct Origin {
    uint32 srcEid;
    bytes32 sender;
    uint64 nonce;
}

interface ILayerZeroEndpointV2 is IMessageLibManager, IMessagingComposer, IMessagingChannel, IMessagingContext {
    event PacketSent(bytes encodedPayload, bytes options, address sendLibrary);

    event PacketVerified(Origin origin, address receiver, bytes32 payloadHash);

    event PacketDelivered(Origin origin, address receiver);

    event LzReceiveAlert(
        address indexed receiver,
        address indexed executor,
        Origin origin,
        bytes32 guid,
        uint256 gas,
        uint256 value,
        bytes message,
        bytes extraData,
        bytes reason
    );

    event LzTokenSet(address token);

    event DelegateSet(address sender, address delegate);

    function quote(MessagingParams calldata _params, address _sender) external view returns (MessagingFee memory);

    function send(
        MessagingParams calldata _params,
        address _refundAddress
    ) external payable returns (MessagingReceipt memory);

    function verify(Origin calldata _origin, address _receiver, bytes32 _payloadHash) external;

    function verifiable(Origin calldata _origin, address _receiver) external view returns (bool);

    function initializable(Origin calldata _origin, address _receiver) external view returns (bool);

    function lzReceive(
        Origin calldata _origin,
        address _receiver,
        bytes32 _guid,
        bytes calldata _message,
        bytes calldata _extraData
    ) external payable;

    // oapp can burn messages partially by calling this function with its own business logic if messages are verified in order
    function clear(address _oapp, Origin calldata _origin, bytes32 _guid, bytes calldata _message) external;

    function setLzToken(address _lzToken) external;

    function lzToken() external view returns (address);

    function nativeToken() external view returns (address);

    function setDelegate(address _delegate) external;
}

File 7 of 18 : IMessageLibManager.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

struct SetConfigParam {
    uint32 eid;
    uint32 configType;
    bytes config;
}

interface IMessageLibManager {
    struct Timeout {
        address lib;
        uint256 expiry;
    }

    event LibraryRegistered(address newLib);
    event DefaultSendLibrarySet(uint32 eid, address newLib);
    event DefaultReceiveLibrarySet(uint32 eid, address newLib);
    event DefaultReceiveLibraryTimeoutSet(uint32 eid, address oldLib, uint256 expiry);
    event SendLibrarySet(address sender, uint32 eid, address newLib);
    event ReceiveLibrarySet(address receiver, uint32 eid, address newLib);
    event ReceiveLibraryTimeoutSet(address receiver, uint32 eid, address oldLib, uint256 timeout);

    function registerLibrary(address _lib) external;

    function isRegisteredLibrary(address _lib) external view returns (bool);

    function getRegisteredLibraries() external view returns (address[] memory);

    function setDefaultSendLibrary(uint32 _eid, address _newLib) external;

    function defaultSendLibrary(uint32 _eid) external view returns (address);

    function setDefaultReceiveLibrary(uint32 _eid, address _newLib, uint256 _gracePeriod) external;

    function defaultReceiveLibrary(uint32 _eid) external view returns (address);

    function setDefaultReceiveLibraryTimeout(uint32 _eid, address _lib, uint256 _expiry) external;

    function defaultReceiveLibraryTimeout(uint32 _eid) external view returns (address lib, uint256 expiry);

    function isSupportedEid(uint32 _eid) external view returns (bool);

    function isValidReceiveLibrary(address _receiver, uint32 _eid, address _lib) external view returns (bool);

    /// ------------------- OApp interfaces -------------------
    function setSendLibrary(address _oapp, uint32 _eid, address _newLib) external;

    function getSendLibrary(address _sender, uint32 _eid) external view returns (address lib);

    function isDefaultSendLibrary(address _sender, uint32 _eid) external view returns (bool);

    function setReceiveLibrary(address _oapp, uint32 _eid, address _newLib, uint256 _gracePeriod) external;

    function getReceiveLibrary(address _receiver, uint32 _eid) external view returns (address lib, bool isDefault);

    function setReceiveLibraryTimeout(address _oapp, uint32 _eid, address _lib, uint256 _expiry) external;

    function receiveLibraryTimeout(address _receiver, uint32 _eid) external view returns (address lib, uint256 expiry);

    function setConfig(address _oapp, address _lib, SetConfigParam[] calldata _params) external;

    function getConfig(
        address _oapp,
        address _lib,
        uint32 _eid,
        uint32 _configType
    ) external view returns (bytes memory config);
}

File 8 of 18 : IMessagingChannel.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

interface IMessagingChannel {
    event InboundNonceSkipped(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce);
    event PacketNilified(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);
    event PacketBurnt(uint32 srcEid, bytes32 sender, address receiver, uint64 nonce, bytes32 payloadHash);

    function eid() external view returns (uint32);

    // this is an emergency function if a message cannot be verified for some reasons
    // required to provide _nextNonce to avoid race condition
    function skip(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce) external;

    function nilify(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;

    function burn(address _oapp, uint32 _srcEid, bytes32 _sender, uint64 _nonce, bytes32 _payloadHash) external;

    function nextGuid(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (bytes32);

    function inboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);

    function outboundNonce(address _sender, uint32 _dstEid, bytes32 _receiver) external view returns (uint64);

    function inboundPayloadHash(
        address _receiver,
        uint32 _srcEid,
        bytes32 _sender,
        uint64 _nonce
    ) external view returns (bytes32);

    function lazyInboundNonce(address _receiver, uint32 _srcEid, bytes32 _sender) external view returns (uint64);
}

File 9 of 18 : IMessagingComposer.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

interface IMessagingComposer {
    event ComposeSent(address from, address to, bytes32 guid, uint16 index, bytes message);
    event ComposeDelivered(address from, address to, bytes32 guid, uint16 index);
    event LzComposeAlert(
        address indexed from,
        address indexed to,
        address indexed executor,
        bytes32 guid,
        uint16 index,
        uint256 gas,
        uint256 value,
        bytes message,
        bytes extraData,
        bytes reason
    );

    function composeQueue(
        address _from,
        address _to,
        bytes32 _guid,
        uint16 _index
    ) external view returns (bytes32 messageHash);

    function sendCompose(address _to, bytes32 _guid, uint16 _index, bytes calldata _message) external;

    function lzCompose(
        address _from,
        address _to,
        bytes32 _guid,
        uint16 _index,
        bytes calldata _message,
        bytes calldata _extraData
    ) external payable;
}

File 10 of 18 : IMessagingContext.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

interface IMessagingContext {
    function isSendingMessage() external view returns (bool);

    function getSendContext() external view returns (uint32 dstEid, address sender);
}

File 11 of 18 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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 {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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);
    }
}

File 12 of 18 : IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @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.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
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].
     *
     * CAUTION: See Security Considerations above.
     */
    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);
}

File 13 of 18 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 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);
}

File 14 of 18 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../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;

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @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);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @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).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // 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 cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}

File 15 of 18 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) 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 FailedInnerCall();
        }
    }
}

File 16 of 18 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 17 of 18 : IClaim.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.22;

import { MessagingReceipt } from "@layerzerolabs/lz-evm-protocol-v2/contracts/interfaces/ILayerZeroEndpointV2.sol";

// solhint-disable-next-line no-unused-import
import { IDonate, Currency, Donation } from "../donate/IDonate.sol";

interface IClaim {
    // Custom Errors
    error AlreadyClaimed(address user);
    error InsufficientDonation(Currency currency, uint256 expectedAmount, uint256 actualAmount);
    error InvalidProof();
    error InvalidNativeStargate();
    error InvalidNativePrice();
    error OnlyDonateAndClaim();
    error DonateAndClaimAlreadySet();
    error WithdrawFailed();
    error MsgValueNotSupported();
    error InvalidToAddress();

    // Events
    event MerkleRootSet(bytes32 merkleRoot);
    event ZRORequested(address requester, uint256 zroAmount, address to);
    event DonateAndClaimSet(address donateAndClaim);
    event ZroWithdrawn(address to, uint256 amount);
    event NativeWithdrawn(address to, uint256 amount);

    // Functions
    function claim(
        Currency currency,
        uint256 zroAmount,
        bytes32[] calldata proof,
        address to,
        bytes calldata extraBytes
    ) external payable returns (MessagingReceipt memory receipt);

    function claim(
        address user,
        Currency currency,
        uint256 zroAmount,
        bytes32[] calldata proof,
        address to,
        bytes calldata extraBytes
    ) external payable returns (MessagingReceipt memory receipt);
}

File 18 of 18 : IDonate.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.22;

enum Currency {
    USDC,
    USDT,
    Native
}

struct Donation {
    uint256 usdc;
    uint256 usdt;
    uint256 native;
}

interface IDonate {
    // Custom Errors
    error InsufficientMsgValue();
    error InsufficientBalance();
    error UnsupportedCurrency(Currency currency);
    error WithdrawDonationFailed();
    error InvalidNativeStargate();
    error InvalidDonationReceiver();
    error UnexpectedMsgValue();

    // Events
    event Donated(Currency currency, address from, address beneficiary, uint256 amount);
    event DonationWithdrawn(Currency currency, address to, uint256 amount);

    // Functions
    function getDonation(address user) external view returns (Donation memory donation);
    function withdrawDonation(Currency currency, uint256 minAmount) external payable;
    function donate(Currency currency, uint256 amount, address beneficiary) external payable;
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_donateContract","type":"address"},{"internalType":"address","name":"_claimContract","type":"address"},{"internalType":"address","name":"_stargateUsdc","type":"address"},{"internalType":"address","name":"_stargateUsdt","type":"address"},{"internalType":"address","name":"_stargateNative","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InsufficientMsgValue","type":"error"},{"inputs":[],"name":"InvalidNativeStargate","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"enum Currency","name":"currency","type":"uint8"}],"name":"UnsupportedCurrency","type":"error"},{"inputs":[],"name":"claimContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Currency","name":"currency","type":"uint8"},{"internalType":"uint256","name":"amountToDonate","type":"uint256"},{"internalType":"uint256","name":"_zroAmount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_extraBytes","type":"bytes"}],"name":"donateAndClaim","outputs":[{"components":[{"internalType":"bytes32","name":"guid","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"},{"components":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"lzTokenFee","type":"uint256"}],"internalType":"struct MessagingFee","name":"fee","type":"tuple"}],"internalType":"struct MessagingReceipt","name":"receipt","type":"tuple"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"donateContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stargateNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stargateUsdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stargateUsdt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenUsdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenUsdt","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101606040523480156200001257600080fd5b506040516200126038038062001260833981016040819052620000359162000595565b6001600160a01b0380861660805284811660a052831615620000e3576001600160a01b03831660c081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa1580156200009c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000c2919062000605565b6001600160a01b0316610120819052608051620000e391906000196200023d565b6001600160a01b0382161562000185576001600160a01b03821660e081905260408051637e062a3560e11b8152905163fc0c546a916004808201926020929091908290030181865afa1580156200013e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000164919062000605565b6001600160a01b03166101408190526080516200018591906000196200023d565b6001600160a01b0381161562000232576001600160a01b03811661010081905260408051637e062a3560e11b815290516000929163fc0c546a9160048083019260209291908290030181865afa158015620001e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020a919062000605565b6001600160a01b0316146200023257604051630692f76560e01b815260040160405180910390fd5b505050505062000678565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200029790859083906200030916565b6200030357604080516001600160a01b038516602482015260006044808301919091528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620002f7918691620003ba16565b620003038482620003ba565b50505050565b6000806000846001600160a01b03168460405162000328919062000623565b6000604051808303816000865af19150503d806000811462000367576040519150601f19603f3d011682016040523d82523d6000602084013e6200036c565b606091505b50915091508180156200039a5750805115806200039a5750808060200190518101906200039a919062000654565b8015620003b157506000856001600160a01b03163b115b95945050505050565b6000620003d16001600160a01b038416836200042d565b90508051600014158015620003f9575080806020019051810190620003f7919062000654565b155b156200042857604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b505050565b60606200043d8383600062000444565b9392505050565b6060814710156200046b5760405163cd78605960e01b81523060048201526024016200041f565b600080856001600160a01b0316848660405162000489919062000623565b60006040518083038185875af1925050503d8060008114620004c8576040519150601f19603f3d011682016040523d82523d6000602084013e620004cd565b606091505b509092509050620004e0868383620004ea565b9695505050505050565b6060826200050357620004fd826200054e565b6200043d565b81511580156200051b57506001600160a01b0384163b155b156200054657604051639996b31560e01b81526001600160a01b03851660048201526024016200041f565b50806200043d565b8051156200055f5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b80516001600160a01b03811681146200059057600080fd5b919050565b600080600080600060a08688031215620005ae57600080fd5b620005b98662000578565b9450620005c96020870162000578565b9350620005d96040870162000578565b9250620005e96060870162000578565b9150620005f96080870162000578565b90509295509295909350565b6000602082840312156200061857600080fd5b6200043d8262000578565b6000825160005b818110156200064657602081860181015185830152016200062a565b506000920191825250919050565b6000602082840312156200066757600080fd5b815180151581146200043d57600080fd5b60805160a05160c05160e051610100516101205161014051610b5e620007026000396000818160e301526103440152600081816101b301526102ba01526000818161017f015261038a01526000818161023301526103070152600081816092015261027d01526000818161014b0152610499015260008181610117015261042a0152610b5e6000f3fe60806040526004361061007b5760003560e01c80639104ab831161004e5780639104ab831461016d57806395e5922c146101a1578063ac6ae3ee146101d5578063fd3072721461022157600080fd5b806317134a58146100805780633b7acec6146100d1578063569f9b771461010557806366345da414610139575b600080fd5b34801561008c57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100dd57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b34801561011157600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b34801561014557600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b34801561017957600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b3480156101ad57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b6101e86101e33660046107f4565b610255565b604080518251815260208084015167ffffffffffffffff16818301529282015180519282019290925291015160608201526080016100c8565b34801561022d57600080fd5b506100b47f000000000000000000000000000000000000000000000000000000000000000081565b61025d610747565b600080808b6002811115610273576102736108cd565b1480156102a857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b156102e9576102e26001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308d610544565b5034610413565b60018b60028111156102fd576102fd6108cd565b14801561033257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b1561036c576102e26001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308d610544565b60028b6002811115610380576103806108cd565b1480156103b557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b156103ef57893410156103db57604051633c79c7bb60e11b815260040160405180910390fd5b8991506103e882346108e3565b9050610413565b8a60405163de0a0bd160e01b815260040161040a9190610926565b60405180910390fd5b604051636689cba160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cd139742908490610465908f908f903390600401610934565b6000604051808303818588803b15801561047e57600080fd5b505af1158015610492573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638b2eddf982338e8d8d8d8d8d8d6040518a63ffffffff1660e01b81526004016104f2989796959493929190610961565b60806040518083038185885af1158015610510573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105359190610a33565b9b9a5050505050505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261059e9085906105a4565b50505050565b60006105b96001600160a01b0384168361060c565b905080516000141580156105de5750808060200190518101906105dc9190610ad7565b155b1561060757604051635274afe760e01b81526001600160a01b038416600482015260240161040a565b505050565b606061061a83836000610623565b90505b92915050565b6060814710156106485760405163cd78605960e01b815230600482015260240161040a565b600080856001600160a01b031684866040516106649190610af9565b60006040518083038185875af1925050503d80600081146106a1576040519150601f19603f3d011682016040523d82523d6000602084013e6106a6565b606091505b50915091506106b68683836106c2565b925050505b9392505050565b6060826106d7576106d28261071e565b6106bb565b81511580156106ee57506001600160a01b0384163b155b1561071757604051639996b31560e01b81526001600160a01b038516600482015260240161040a565b50806106bb565b80511561072e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b604051806060016040528060008019168152602001600067ffffffffffffffff16815260200161078a604051806040016040528060008152602001600081525090565b905290565b80356001600160a01b03811681146107a657600080fd5b919050565b60008083601f8401126107bd57600080fd5b50813567ffffffffffffffff8111156107d557600080fd5b6020830191508360208285010111156107ed57600080fd5b9250929050565b60008060008060008060008060c0898b03121561081057600080fd5b88356003811061081f57600080fd5b97506020890135965060408901359550606089013567ffffffffffffffff8082111561084a57600080fd5b818b0191508b601f83011261085e57600080fd5b81358181111561086d57600080fd5b8c60208260051b850101111561088257600080fd5b602083019750955061089660808c0161078f565b945060a08b01359150808211156108ac57600080fd5b506108b98b828c016107ab565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b8181038181111561061d57634e487b7160e01b600052601160045260246000fd5b6003811061092257634e487b7160e01b600052602160045260246000fd5b9052565b6020810161061d8284610904565b606081016109428286610904565b60208201939093526001600160a01b0391909116604090910152919050565b6001600160a01b03898116825260009061097e602084018b610904565b6040830189905260c06060840181905283018790526001600160fb1b038711156109a757600080fd5b8660051b808960e08601379086166080840152820182810360e090810160a08501528101849052610100908486838301376000818601830152601f909401601f19169093019092019998505050505050505050565b6040805190810167ffffffffffffffff81118282101715610a2d57634e487b7160e01b600052604160045260246000fd5b60405290565b60008183036080811215610a4657600080fd5b6040516060810167ffffffffffffffff8282108183111715610a7857634e487b7160e01b600052604160045260246000fd5b8160405285518352602086015191508082168214610a9557600080fd5b5060208201526040603f1983011215610aad57600080fd5b610ab56109fc565b6040858101518252606090950151602082015293810193909352509092915050565b600060208284031215610ae957600080fd5b815180151581146106bb57600080fd5b6000825160005b81811015610b1a5760208186018101518583015201610b00565b50600092019182525091905056fea26469706673582212200dedb6e64976d2dfc57a48d634cf01d1fefe317ce1cd5d6a0f110f35fbdc45d864736f6c63430008160033000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245000000000000000000000000d6b6a6701303b5ea36fa0edf7389b562d8f894db000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f

Deployed Bytecode

0x60806040526004361061007b5760003560e01c80639104ab831161004e5780639104ab831461016d57806395e5922c146101a1578063ac6ae3ee146101d5578063fd3072721461022157600080fd5b806317134a58146100805780633b7acec6146100d1578063569f9b771461010557806366345da414610139575b600080fd5b34801561008c57600080fd5b506100b47f000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d381565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100dd57600080fd5b506100b47f000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb981565b34801561011157600080fd5b506100b47f000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b24581565b34801561014557600080fd5b506100b47f000000000000000000000000d6b6a6701303b5ea36fa0edf7389b562d8f894db81565b34801561017957600080fd5b506100b47f000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f81565b3480156101ad57600080fd5b506100b47f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e583181565b6101e86101e33660046107f4565b610255565b604080518251815260208084015167ffffffffffffffff16818301529282015180519282019290925291015160608201526080016100c8565b34801561022d57600080fd5b506100b47f000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d081565b61025d610747565b600080808b6002811115610273576102736108cd565b1480156102a857507f000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d36001600160a01b031615155b156102e9576102e26001600160a01b037f000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e58311633308d610544565b5034610413565b60018b60028111156102fd576102fd6108cd565b14801561033257507f000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d06001600160a01b031615155b1561036c576102e26001600160a01b037f000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb91633308d610544565b60028b6002811115610380576103806108cd565b1480156103b557507f000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f6001600160a01b031615155b156103ef57893410156103db57604051633c79c7bb60e11b815260040160405180910390fd5b8991506103e882346108e3565b9050610413565b8a60405163de0a0bd160e01b815260040161040a9190610926565b60405180910390fd5b604051636689cba160e11b81526001600160a01b037f000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245169063cd139742908490610465908f908f903390600401610934565b6000604051808303818588803b15801561047e57600080fd5b505af1158015610492573d6000803e3d6000fd5b50505050507f000000000000000000000000d6b6a6701303b5ea36fa0edf7389b562d8f894db6001600160a01b0316638b2eddf982338e8d8d8d8d8d8d6040518a63ffffffff1660e01b81526004016104f2989796959493929190610961565b60806040518083038185885af1158015610510573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906105359190610a33565b9b9a5050505050505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261059e9085906105a4565b50505050565b60006105b96001600160a01b0384168361060c565b905080516000141580156105de5750808060200190518101906105dc9190610ad7565b155b1561060757604051635274afe760e01b81526001600160a01b038416600482015260240161040a565b505050565b606061061a83836000610623565b90505b92915050565b6060814710156106485760405163cd78605960e01b815230600482015260240161040a565b600080856001600160a01b031684866040516106649190610af9565b60006040518083038185875af1925050503d80600081146106a1576040519150601f19603f3d011682016040523d82523d6000602084013e6106a6565b606091505b50915091506106b68683836106c2565b925050505b9392505050565b6060826106d7576106d28261071e565b6106bb565b81511580156106ee57506001600160a01b0384163b155b1561071757604051639996b31560e01b81526001600160a01b038516600482015260240161040a565b50806106bb565b80511561072e5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b604051806060016040528060008019168152602001600067ffffffffffffffff16815260200161078a604051806040016040528060008152602001600081525090565b905290565b80356001600160a01b03811681146107a657600080fd5b919050565b60008083601f8401126107bd57600080fd5b50813567ffffffffffffffff8111156107d557600080fd5b6020830191508360208285010111156107ed57600080fd5b9250929050565b60008060008060008060008060c0898b03121561081057600080fd5b88356003811061081f57600080fd5b97506020890135965060408901359550606089013567ffffffffffffffff8082111561084a57600080fd5b818b0191508b601f83011261085e57600080fd5b81358181111561086d57600080fd5b8c60208260051b850101111561088257600080fd5b602083019750955061089660808c0161078f565b945060a08b01359150808211156108ac57600080fd5b506108b98b828c016107ab565b999c989b5096995094979396929594505050565b634e487b7160e01b600052602160045260246000fd5b8181038181111561061d57634e487b7160e01b600052601160045260246000fd5b6003811061092257634e487b7160e01b600052602160045260246000fd5b9052565b6020810161061d8284610904565b606081016109428286610904565b60208201939093526001600160a01b0391909116604090910152919050565b6001600160a01b03898116825260009061097e602084018b610904565b6040830189905260c06060840181905283018790526001600160fb1b038711156109a757600080fd5b8660051b808960e08601379086166080840152820182810360e090810160a08501528101849052610100908486838301376000818601830152601f909401601f19169093019092019998505050505050505050565b6040805190810167ffffffffffffffff81118282101715610a2d57634e487b7160e01b600052604160045260246000fd5b60405290565b60008183036080811215610a4657600080fd5b6040516060810167ffffffffffffffff8282108183111715610a7857634e487b7160e01b600052604160045260246000fd5b8160405285518352602086015191508082168214610a9557600080fd5b5060208201526040603f1983011215610aad57600080fd5b610ab56109fc565b6040858101518252606090950151602082015293810193909352509092915050565b600060208284031215610ae957600080fd5b815180151581146106bb57600080fd5b6000825160005b81811015610b1a5760208186018101518583015201610b00565b50600092019182525091905056fea26469706673582212200dedb6e64976d2dfc57a48d634cf01d1fefe317ce1cd5d6a0f110f35fbdc45d864736f6c63430008160033

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

000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245000000000000000000000000d6b6a6701303b5ea36fa0edf7389b562d8f894db000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f

-----Decoded View---------------
Arg [0] : _donateContract (address): 0xa86Da1141eB193Ea9DA56c70c286b64dEf66b245
Arg [1] : _claimContract (address): 0xd6b6a6701303B5Ea36fa0eDf7389b562d8F894DB
Arg [2] : _stargateUsdc (address): 0xe8CDF27AcD73a434D661C84887215F7598e7d0d3
Arg [3] : _stargateUsdt (address): 0xcE8CcA271Ebc0533920C83d39F417ED6A0abB7D0
Arg [4] : _stargateNative (address): 0xA45B5130f36CDcA45667738e2a258AB09f4A5f7F

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000a86da1141eb193ea9da56c70c286b64def66b245
Arg [1] : 000000000000000000000000d6b6a6701303b5ea36fa0edf7389b562d8f894db
Arg [2] : 000000000000000000000000e8cdf27acd73a434d661c84887215f7598e7d0d3
Arg [3] : 000000000000000000000000ce8cca271ebc0533920c83d39f417ed6a0abb7d0
Arg [4] : 000000000000000000000000a45b5130f36cdca45667738e2a258ab09f4a5f7f


Deployed Bytecode Sourcemap

496:3296:15:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;766:37;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;178:32:18;;;160:51;;148:2;133:18;766:37:15;;;;;;;;937:33;;;;;;;;;;;;;;;559:39;;;;;;;;;;;;;;;604:38;;;;;;;;;;;;;;;852:39;;;;;;;;;;;;;;;898:33;;;;;;;;;;;;;;;2221:1569;;;;;;:::i;:::-;;:::i;:::-;;;;2483:13:18;;2465:32;;2557:4;2545:17;;;2539:24;2565:18;2535:49;2513:20;;;2506:79;2620:17;;;2614:24;2676:19;;2654:20;;;2647:49;;;;2738:23;;2732:30;2727:2;2712:18;;2705:58;2452:3;2437:19;2221:1569:15;2252:517:18;809:37:15;;;;;;;;;;;;;;;2221:1569;2456:31;;:::i;:::-;2499:26;;;2638:8;:25;;;;;;;;:::i;:::-;;:55;;;;-1:-1:-1;2667:12:15;-1:-1:-1;;;;;2667:26:15;;;2638:55;2634:885;;;2709:69;-1:-1:-1;;;;;2709:9:15;:26;2736:10;2756:4;2763:14;2709:26;:69::i;:::-;-1:-1:-1;2841:9:15;2634:885;;;2883:13;2871:8;:25;;;;;;;;:::i;:::-;;:55;;;;-1:-1:-1;2900:12:15;-1:-1:-1;;;;;2900:26:15;;;2871:55;2867:652;;;2942:69;-1:-1:-1;;;;;2942:9:15;:26;2969:10;2989:4;2996:14;2942:26;:69::i;2867:652::-;3116:15;3104:8;:27;;;;;;;;:::i;:::-;;:59;;;;-1:-1:-1;3135:14:15;-1:-1:-1;;;;;3135:28:15;;;3104:59;3100:419;;;3195:14;3183:9;:26;3179:69;;;3218:30;;-1:-1:-1;;;3218:30:15;;;;;;;;;;;3179:69;3284:14;;-1:-1:-1;3321:30:15;3284:14;3321:9;:30;:::i;:::-;3312:39;;3100:419;;;3499:8;3471:37;;-1:-1:-1;;;3471:37:15;;;;;;;;:::i;:::-;;;;;;;;3100:419;3547:97;;-1:-1:-1;;;3547:97:15;;-1:-1:-1;;;;;3555:14:15;3547:30;;;;3586:18;;3547:97;;3607:8;;3617:14;;3633:10;;3547:97;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3686:13;-1:-1:-1;;;;;3679:27:15;;3715:6;3724:10;3736:8;3746:10;3758:6;;3766:3;3771:11;;3679:104;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3672:111;2221:1569;-1:-1:-1;;;;;;;;;;;2221:1569:15:o;1702:188:12:-;1829:53;;;-1:-1:-1;;;;;6720:15:18;;;1829:53:12;;;6702:34:18;6772:15;;6752:18;;;6745:43;6804:18;;;;6797:34;;;1829:53:12;;;;;;;;;;6637:18:18;;;;1829:53:12;;;;;;;;-1:-1:-1;;;;;1829:53:12;-1:-1:-1;;;1829:53:12;;;1802:81;;1822:5;;1802:19;:81::i;:::-;1702:188;;;;:::o;4059:629::-;4478:23;4504:33;-1:-1:-1;;;;;4504:27:12;;4532:4;4504:27;:33::i;:::-;4478:59;;4551:10;:17;4572:1;4551:22;;:57;;;;;4589:10;4578:30;;;;;;;;;;;;:::i;:::-;4577:31;4551:57;4547:135;;;4631:40;;-1:-1:-1;;;4631:40:12;;-1:-1:-1;;;;;178:32:18;;4631:40:12;;;160:51:18;133:18;;4631:40:12;14:203:18;4547:135:12;4129:559;4059:629;;:::o;2705:151:13:-;2780:12;2811:38;2833:6;2841:4;2847:1;2811:21;:38::i;:::-;2804:45;;2705:151;;;;;:::o;3180:392::-;3279:12;3331:5;3307:21;:29;3303:108;;;3359:41;;-1:-1:-1;;;3359:41:13;;3394:4;3359:41;;;160:51:18;133:18;;3359:41:13;14:203:18;3303:108:13;3421:12;3435:23;3462:6;-1:-1:-1;;;;;3462:11:13;3481:5;3488:4;3462:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3420:73;;;;3510:55;3537:6;3545:7;3554:10;3510:26;:55::i;:::-;3503:62;;;;3180:392;;;;;;:::o;4625:582::-;4769:12;4798:7;4793:408;;4821:19;4829:10;4821:7;:19::i;:::-;4793:408;;;5045:17;;:22;:49;;;;-1:-1:-1;;;;;;5071:18:13;;;:23;5045:49;5041:119;;;5121:24;;-1:-1:-1;;;5121:24:13;;-1:-1:-1;;;;;178:32:18;;5121:24:13;;;160:51:18;133:18;;5121:24:13;14:203:18;5041:119:13;-1:-1:-1;5180:10:13;5173:17;;5743:516;5874:17;;:21;5870:383;;6102:10;6096:17;6158:15;6145:10;6141:2;6137:19;6130:44;5870:383;6225:17;;-1:-1:-1;;;6225:17:13;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;445:173:18:-;513:20;;-1:-1:-1;;;;;562:31:18;;552:42;;542:70;;608:1;605;598:12;542:70;445:173;;;:::o;623:347::-;674:8;684:6;738:3;731:4;723:6;719:17;715:27;705:55;;756:1;753;746:12;705:55;-1:-1:-1;779:20:18;;822:18;811:30;;808:50;;;854:1;851;844:12;808:50;891:4;883:6;879:17;867:29;;943:3;936:4;927:6;919;915:19;911:30;908:39;905:59;;;960:1;957;950:12;905:59;623:347;;;;;:::o;975:1272::-;1130:6;1138;1146;1154;1162;1170;1178;1186;1239:3;1227:9;1218:7;1214:23;1210:33;1207:53;;;1256:1;1253;1246:12;1207:53;1295:9;1282:23;1334:1;1327:5;1324:12;1314:40;;1350:1;1347;1340:12;1314:40;1373:5;-1:-1:-1;1425:2:18;1410:18;;1397:32;;-1:-1:-1;1476:2:18;1461:18;;1448:32;;-1:-1:-1;1531:2:18;1516:18;;1503:32;1554:18;1584:14;;;1581:34;;;1611:1;1608;1601:12;1581:34;1649:6;1638:9;1634:22;1624:32;;1694:7;1687:4;1683:2;1679:13;1675:27;1665:55;;1716:1;1713;1706:12;1665:55;1756:2;1743:16;1782:2;1774:6;1771:14;1768:34;;;1798:1;1795;1788:12;1768:34;1851:7;1846:2;1836:6;1833:1;1829:14;1825:2;1821:23;1817:32;1814:45;1811:65;;;1872:1;1869;1862:12;1811:65;1903:2;1895:11;;;-1:-1:-1;1925:6:18;-1:-1:-1;1950:39:18;1984:3;1969:19;;1950:39;:::i;:::-;1940:49;;2042:3;2031:9;2027:19;2014:33;1998:49;;2072:2;2062:8;2059:16;2056:36;;;2088:1;2085;2078:12;2056:36;;2127:60;2179:7;2168:8;2157:9;2153:24;2127:60;:::i;:::-;975:1272;;;;-1:-1:-1;975:1272:18;;-1:-1:-1;975:1272:18;;;;;;2206:8;-1:-1:-1;;;975:1272:18:o;2774:127::-;2835:10;2830:3;2826:20;2823:1;2816:31;2866:4;2863:1;2856:15;2890:4;2887:1;2880:15;2906:225;2973:9;;;2994:11;;;2991:134;;;3047:10;3042:3;3038:20;3035:1;3028:31;3082:4;3079:1;3072:15;3110:4;3107:1;3100:15;3136:236;3216:1;3209:5;3206:12;3196:143;;3261:10;3256:3;3252:20;3249:1;3242:31;3296:4;3293:1;3286:15;3324:4;3321:1;3314:15;3196:143;3348:18;;3136:236::o;3377:206::-;3522:2;3507:18;;3534:43;3511:9;3559:6;3534:43;:::i;3588:374::-;3789:2;3774:18;;3801:43;3778:9;3826:6;3801:43;:::i;:::-;3875:2;3860:18;;3853:34;;;;-1:-1:-1;;;;;3923:32:18;;;;3918:2;3903:18;;;3896:60;3588:374;;-1:-1:-1;3588:374:18:o;3967:1148::-;-1:-1:-1;;;;;4373:15:18;;;4355:34;;4298:4;;4398:52;4446:2;4431:18;;4423:6;4398:52;:::i;:::-;4481:2;4466:18;;4459:34;;;4529:3;4524:2;4509:18;;4502:31;;;4549:19;;4542:35;;;-1:-1:-1;;;;;4589:31:18;;4586:51;;;4633:1;4630;4623:12;4586:51;4667:6;4664:1;4660:14;4725:6;4717;4711:3;4700:9;4696:19;4683:49;4810:15;;;4804:3;4789:19;;4782:44;4751:22;;4867:18;;;4887:3;4863:28;;;4857:3;4842:19;;4835:57;4908:12;;4901:28;;;4948:3;;4922:6;4986;4973:11;;;4960:41;5043:1;5021:15;;;5017:24;;5010:35;5099:2;5078:15;;;-1:-1:-1;;5074:29:18;5066:38;;;5062:47;;;;3967:1148;-1:-1:-1;;;;;;;;;3967:1148:18:o;5120:343::-;5187:2;5181:9;;;5217:15;;5262:18;5247:34;;5283:22;;;5244:62;5241:185;;;5348:10;5343:3;5339:20;5336:1;5329:31;5383:4;5380:1;5373:15;5411:4;5408:1;5401:15;5241:185;5442:2;5435:22;5120:343;:::o;5468:989::-;5571:6;5615:9;5606:7;5602:23;5645:3;5641:2;5637:12;5634:32;;;5662:1;5659;5652:12;5634:32;5695:2;5689:9;5737:4;5729:6;5725:17;5761:18;5829:6;5817:10;5814:22;5809:2;5797:10;5794:18;5791:46;5788:169;;;5879:10;5874:3;5870:20;5867:1;5860:31;5914:4;5911:1;5904:15;5942:4;5939:1;5932:15;5788:169;5977:10;5973:2;5966:22;6018:9;6012:16;6004:6;5997:32;6072:2;6061:9;6057:18;6051:25;6038:38;;6116:2;6109:5;6105:14;6098:5;6095:25;6085:53;;6134:1;6131;6124:12;6085:53;-1:-1:-1;6166:2:18;6154:15;;6147:30;6211:2;-1:-1:-1;;6193:16:18;;6189:25;6186:45;;;6227:1;6224;6217:12;6186:45;6255:17;;:::i;:::-;6318:2;6303:18;;;6297:25;6281:42;;6378:4;6363:20;;;6357:27;6352:2;6339:16;;6332:53;6401:15;;;6394:32;;;;-1:-1:-1;6405:6:18;;5468:989;-1:-1:-1;;5468:989:18:o;6842:277::-;6909:6;6962:2;6950:9;6941:7;6937:23;6933:32;6930:52;;;6978:1;6975;6968:12;6930:52;7010:9;7004:16;7063:5;7056:13;7049:21;7042:5;7039:32;7029:60;;7085:1;7082;7075:12;7124:412;7253:3;7291:6;7285:13;7316:1;7326:129;7340:6;7337:1;7334:13;7326:129;;;7438:4;7422:14;;;7418:25;;7412:32;7399:11;;;7392:53;7355:12;7326:129;;;-1:-1:-1;7510:1:18;7474:16;;7499:13;;;-1:-1:-1;7474:16:18;7124:412;-1:-1:-1;7124:412:18:o

Swarm Source

ipfs://0dedb6e64976d2dfc57a48d634cf01d1fefe317ce1cd5d6a0f110f35fbdc45d8

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

OVERVIEW

Proof of Donation Claim 1

Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
ARB90.50%$2.692,588.6673$6,963.52
ARB0.01%$0.9998631.0345$1.03
ARB0.01%$11$1
ZKSYNC2.30%$1,783.130.0994$177.22
SCROLL2.02%$1,783.130.087$155.12
OP1.47%$1,783.050.0635$113.23
BASE1.43%$1,783.250.0616$109.79
LINEA0.99%$1,783.130.0428$76.28
ETH0.94%$1,783.130.0404$72.1
BSC0.12%$616.910.0151$9.29
BSC0.04%$13$3
BLAST0.08%$1,783.450.00362888$6.47
ARBNOVA0.05%$1,782.350.00231806$4.13
TAIKO0.02%$1,783.130.00105624$1.88
AVAX<0.01%$22.730.00233201$0.053002
POL<0.01%$0.2174850.0109$0.002373
CELO<0.01%$0.3290270.00015746$0.000052
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.