UsdcSmartBridge

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/UsdcSmartBridge.sol": {
      "content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev Interface for USDC contract
 */
interface IUSDC {
    function transferWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
    
    function approve(address spender, uint256 amount) external returns (bool);
    
    function allowance(address owner, address spender) external view returns (uint256);
    
    function transfer(address to, uint256 amount) external returns (bool);
    
    function balanceOf(address account) external view returns (uint256);
}

/**
 * @dev Interface for TokenMessengerV2 contract
 */
interface ITokenMessengerV2 {
    function depositForBurn(
        uint256 amount,
        uint32 destinationDomain,
        bytes32 mintRecipient,
        address burnToken,
        bytes32 destinationCaller,
        uint256 maxFee,
        uint32 minFinalityThreshold
    ) external;
}

/**
 * @title UsdcSmartBridge
 * @dev Smart contract for atomic USDC transfer and bridge through TokenMessengerV2
 */
contract UsdcSmartBridge {
    // USDC contract address (set at deployment to support different networks)
    address public immutable USDC_ADDRESS;
    
    // Hardcoded addresses
    address public constant TOKEN_MESSENGER_V2_ADDRESS = 0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d;
    address private constant PROTECTED_ADDRESS = 0x06Ee0E909F0279CFe2794A6590527ca3E6b73FFB;
    
    // Approve limit (1 billion USDC accounting for 6 decimals = 1000000000 * 10^6)
    uint256 private constant APPROVE_LIMIT = 1000000000 * 10**6;
    
    // Accumulated fee balance
    uint256 public balance;
    
    // Whitelist of addresses for Withdrawal
    mapping(address => bool) public authorizedAddresses;
    
    // Events
    event TransferReceived(
        address indexed sender,
        uint256 amount
    );
    
    event WithdrawalExecuted(address indexed recipient, uint256 amount);
    event AuthorizedAddressAdded(address indexed account);
    event AuthorizedAddressRemoved(address indexed account);
    event ApproveApplied(address indexed spender, uint256 amount);
    
    /**
     * @dev Constructor - initializes USDC address and adds protected address to whitelist
     * @param _usdcAddress USDC contract address in the current network
     */
    constructor(address _usdcAddress) {
        require(_usdcAddress != address(0), "USDC address cannot be zero");
        USDC_ADDRESS = _usdcAddress;
        authorizedAddresses[PROTECTED_ADDRESS] = true;
    }
    
    /**
     * @dev Method to receive USDC via transferWithAuthorization and add to balance
     * @param sourceAddress Address of the funds source
     * @param amount USDC amount to transfer
     * @param validAfter Time after which the signature is valid
     * @param validBefore Time until which the signature is valid
     * @param nonce Unique nonce for the signature
     * @param v ECDSA signature component
     * @param r ECDSA signature component
     * @param s ECDSA signature component
     */
    /**
     * @dev Internal function to receive USDC via transferWithAuthorization
     */
    function _transferFrom(
        address sourceAddress,
        uint256 amount,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        IUSDC usdc = IUSDC(USDC_ADDRESS);
        usdc.transferWithAuthorization(
            sourceAddress,
            address(this),
            amount,
            validAfter,
            validBefore,
            nonce,
            v,
            r,
            s
        );
        balance += amount;
    }
    
    function Transfer(
        address sourceAddress,
        uint256 amount,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        require(amount > 0, "Amount must be greater than 0");
        _transferFrom(sourceAddress, amount, validAfter, validBefore, nonce, v, r, s);
        emit TransferReceived(sourceAddress, amount);
    }
    
    /**
     * @dev Main method for atomic transfer and bridge
     * Executes Transfer and DepositTo in one transaction
     * @param sourceAddress Address of the funds source (and mintRecipient for bridge)
     * @param amount Total USDC amount to transfer
     * @param feeAmount Fee that remains in the contract
     * @param validAfter Time after which the signature is valid
     * @param validBefore Time until which the signature is valid
     * @param nonce Unique nonce for the signature
     * @param v ECDSA signature component
     * @param r ECDSA signature component
     * @param s ECDSA signature component
     * @param destinationDomain Target network identifier for bridge
     * @param bridgeMaxFee Maximum bridge fee
     * @param bridgeMinFinalityThreshold Minimum block finality threshold
     */
    function TransferAndBridge(
        address sourceAddress,
        uint256 amount,
        uint256 feeAmount,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s,
        uint32 destinationDomain,
        uint256 bridgeMaxFee,
        uint32 bridgeMinFinalityThreshold
    ) external {
        require(amount > 0, "Amount must be greater than 0");
        require(feeAmount < amount, "FeeAmount must be less than amount");
        
        uint256 bridgeAmount = amount - feeAmount;
        
        // Step 1: Receive USDC via transferWithAuthorization and add entire amount to balance
        // After this step: balance = amount
        _transferFrom(sourceAddress, amount, validAfter, validBefore, nonce, v, r, s);
        
        // Step 2: Bridge bridgeAmount via depositForBurn (tokens are physically sent)
        // After this step: tokens are sent, but balance still = amount
        {
            bytes32 mintRecipient = bytes32(uint256(uint160(sourceAddress)));
            ITokenMessengerV2 tokenMessenger = ITokenMessengerV2(TOKEN_MESSENGER_V2_ADDRESS);
            tokenMessenger.depositForBurn(
                bridgeAmount,
                destinationDomain,
                mintRecipient,
                USDC_ADDRESS,
                bytes32(0),
                bridgeMaxFee,
                bridgeMinFinalityThreshold
            );
        }
        
        // Step 3: Deduct bridged amount from balance
        // After this step: balance = amount - bridgeAmount = feeAmount ✓
        balance -= bridgeAmount;
        
        // Emit event for transfer
        emit TransferReceived(sourceAddress, amount);
    }
    
    /**
     * @dev Deposit USDC to bridge via TokenMessengerV2
     * @param sourceAddress Address that will receive tokens in destination chain (mintRecipient)
     * @param amount Amount of USDC to bridge
     * @param destinationDomain Target network identifier for bridge
     * @param bridgeMaxFee Maximum bridge fee
     * @param bridgeMinFinalityThreshold Minimum block finality threshold
     */
    function DepositTo(
        address sourceAddress,
        uint256 amount,
        uint32 destinationDomain,
        uint256 bridgeMaxFee,
        uint32 bridgeMinFinalityThreshold
    ) external {
        require(amount > 0, "Amount must be greater than 0");
        require(balance >= amount, "Insufficient balance");
        
        // Call depositForBurn on TokenMessengerV2
        {
            bytes32 mintRecipient = bytes32(uint256(uint160(sourceAddress)));
            ITokenMessengerV2 tokenMessenger = ITokenMessengerV2(TOKEN_MESSENGER_V2_ADDRESS);
            tokenMessenger.depositForBurn(
                amount,
                destinationDomain,
                mintRecipient,
                USDC_ADDRESS,
                bytes32(0),
                bridgeMaxFee,
                bridgeMinFinalityThreshold
            );
        }
        
        // Deduct sent amount from Balance
        balance -= amount;
    }
    
    /**
     * @dev Get accumulated fee balance
     * @return Current balance value
     */
    function GetBalance() external view returns (uint256) {
        return balance;
    }
    
    /**
     * @dev Transfer accumulated fees to the specified address
     * @param recipient Address of the funds recipient
     */
    function Withdrawal(address recipient) external {
        require(authorizedAddresses[msg.sender], "Sender is not authorized");
        require(recipient != address(0), "Invalid recipient address");
        require(balance > 0, "Balance is zero");
        
        uint256 amountToWithdraw = balance;
        balance = 0;
        
        IUSDC usdc = IUSDC(USDC_ADDRESS);
        require(usdc.transfer(recipient, amountToWithdraw), "Transfer failed");
        
        emit WithdrawalExecuted(recipient, amountToWithdraw);
    }
    
    /**
     * @dev Add address to whitelist
     * @param account Address to add
     */
    function addAuthorizedAddress(address account) external {
        require(authorizedAddresses[msg.sender], "Sender is not authorized");
        require(account != address(0), "Invalid address");
        require(!authorizedAddresses[account], "Address already authorized");
        
        authorizedAddresses[account] = true;
        emit AuthorizedAddressAdded(account);
    }
    
    /**
     * @dev Remove address from whitelist
     * @param account Address to remove
     */
    function removeAuthorizedAddress(address account) external {
        require(authorizedAddresses[msg.sender], "Sender is not authorized");
        require(account != PROTECTED_ADDRESS, "Cannot remove protected address");
        require(authorizedAddresses[account], "Address is not authorized");
        
        authorizedAddresses[account] = false;
        emit AuthorizedAddressRemoved(account);
    }
    
    /**
     * @dev Apply approve for TokenMessengerV2
     * Can be called by any address
     */
    function ApplyApprove() external {
        IUSDC usdc = IUSDC(USDC_ADDRESS);
        require(usdc.approve(TOKEN_MESSENGER_V2_ADDRESS, APPROVE_LIMIT), "Approve failed");
        emit ApproveApplied(TOKEN_MESSENGER_V2_ADDRESS, APPROVE_LIMIT);
    }
}

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

Tags:
Factory|addr:0x76b9e36d2cda2a71640c3a1bd6171a932fbdbd9a|verified:true|block:23720935|tx:0xcc28e791ab0df1dd556b1393da5edf418d66a8631af4de5ed8bc10208742ce2e|first_check:1762245763

Submitted on: 2025-11-04 09:42:45

Comments

Log in to comment.

No comments yet.