S Price: $0.513045 (-3.72%)

Contract Diff Checker

Contract Name:
SonicVaultDecoderAndSanitizer

Contract Source Code:

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";
import {SonicGatewayDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/SonicGatewayDecoderAndSanitizer.sol"; 
import {OdosDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/OdosDecoderAndSanitizer.sol"; 
import {AaveV3DecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/AaveV3DecoderAndSanitizer.sol"; 
import {SiloDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/SiloDecoderAndSanitizer.sol"; 

contract SonicVaultDecoderAndSanitizer is
    BaseDecoderAndSanitizer,
    SonicGatewayDecoderAndSanitizer,
    OdosDecoderAndSanitizer,
    AaveV3DecoderAndSanitizer,
    SiloDecoderAndSanitizer
{
    constructor(address _odosRouter) OdosDecoderAndSanitizer(_odosRouter){} 
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {DecoderCustomTypes} from "src/interfaces/DecoderCustomTypes.sol";

contract BaseDecoderAndSanitizer {
    error BaseDecoderAndSanitizer__FunctionSelectorNotSupported();
    //============================== IMMUTABLES ===============================

    function approve(address spender, uint256) external pure returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(spender);
    }

    function transfer(address _to, uint256) external pure returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(_to);
    }

    function claimFees(address feeAsset) external pure returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(feeAsset);
    }

    function claimYield(address yieldAsset) external pure returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(yieldAsset);
    }

    function withdrawNonBoringToken(address token, uint256 /*amount*/ )
        external
        pure
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(token);
    }

    function withdrawNativeFromDrone() external pure returns (bytes memory addressesFound) {
        return addressesFound;
    }

    //============================== FALLBACK ===============================
    /**
     * @notice The purpose of this function is to revert with a known error,
     *         so that during merkle tree creation we can verify that a
     *         leafs decoder and sanitizer implments the required function
     *         selector.
     */
    fallback() external {
        revert BaseDecoderAndSanitizer__FunctionSelectorNotSupported();
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";

abstract contract SonicGatewayDecoderAndSanitizer is BaseDecoderAndSanitizer {
    ////////////////// Sonic Gateway //////////////////

    //bridges mainnet -> sonic
    function deposit(uint96, /*uid*/ address token, uint256 /*amount*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        return abi.encodePacked(token);
    }

    //bridges sonic -> mainnet
    function withdraw(uint96, /*uid*/ address token, uint256 /*amount*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        return abi.encodePacked(token);
    }

    function claim(uint256, /*id*/ address token, uint256, /*amount*/ bytes calldata /*proof*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        return abi.encodePacked(token);
    }

    //if the bridge is "dead", we can cancel our deposit if needed
    function cancelDepositWhileDead(uint256, /*id*/ address token, uint256, /*amount*/ bytes calldata /*proof*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        return abi.encodePacked(token);
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer, DecoderCustomTypes} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";


abstract contract OdosDecoderAndSanitizer is BaseDecoderAndSanitizer {

    // Reference to the OdosRouterV2 contract
    IOdosRouterV2 internal immutable odosRouter; //temp

    constructor(address _odosRouter) {
        odosRouter = IOdosRouterV2(_odosRouter); 
    }

    function swap(
        DecoderCustomTypes.swapTokenInfo memory tokenInfo,
        bytes calldata /*pathDefinition*/,
        address executor,
        uint32 /*referralCode*/
    ) external pure virtual returns (bytes memory addressesFound) {
        
        addressesFound = abi.encodePacked(tokenInfo.inputToken, tokenInfo.inputReceiver, tokenInfo.outputToken, tokenInfo.outputReceiver, executor); 

    }

    function swapCompact() external view virtual returns (bytes memory addressesFound) {
        DecoderCustomTypes.swapTokenInfo memory tokenInfo;
        address executor;
        uint32 referralCode;
        bytes calldata pathDefinition;

        // Variables to store indices for addresses that need lookup
        Address memory inputTokenLookup;  
        Address memory outputTokenLookup; 
        Address memory executorLookup; 

        {
            address msgSender = msg.sender;
            assembly {
                // Assembly function to get address from calldata
                function getAddress(currPos) -> result, newPos {
                    let inputPos := shr(240, calldataload(currPos))
                    
                    switch inputPos
                    // Reserve the null address as a special case that can be specified with 2 null bytes
                    case 0x0000 {
                        result := 0
                        newPos := add(currPos, 2)
                    }
                    // This case means that the address is encoded in the calldata directly following the code
                    case 0x0001 {
                        result := and(shr(80, calldataload(currPos)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
                        newPos := add(currPos, 22)
                    }
                    // For addresses from the addressList, we'll just store the index for later retrieval
                    default {
                        // We'll use this later to know we need to look up from addressList
                        result := 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
                        newPos := add(currPos, 2)
                    }
                }
                
                let result := 0
                let pos := 4
                let fromList := 0

                // Load in the input and output token addresses
                result, pos := getAddress(pos)
                if eq(result, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) {
                    let inputPos := shr(240, calldataload(sub(pos, 2))) //sub 2 because we added 2 in `getAddress`, shr 240 bits to get index
                    mstore(add(inputTokenLookup, 0x00), sub(inputPos, 2)) // Store index
                    mstore(add(inputTokenLookup, 0x20), 1)                // Set needsLookup to true
                }
                mstore(tokenInfo, result)

                result, pos := getAddress(pos)
                if eq(result, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) {
                    let inputPos := shr(240, calldataload(sub(pos, 2)))
                    mstore(add(outputTokenLookup, 0x00), sub(inputPos, 2))
                    mstore(add(outputTokenLookup, 0x20), 1)
                }
                mstore(add(tokenInfo, 0x60), result)

                // Load in the input amount - a 0 byte means the full balance is to be used
                let inputAmountLength := shr(248, calldataload(pos))
                pos := add(pos, 1)

                if inputAmountLength {
                  mstore(add(tokenInfo, 0x20), shr(mul(sub(32, inputAmountLength), 8), calldataload(pos)))
                  pos := add(pos, inputAmountLength)
                }

                // Load in the quoted output amount
                let quoteAmountLength := shr(248, calldataload(pos))
                pos := add(pos, 1)

                let outputQuote := shr(mul(sub(32, quoteAmountLength), 8), calldataload(pos))
                mstore(add(tokenInfo, 0x80), outputQuote)
                pos := add(pos, quoteAmountLength)

                // Load the slippage tolerance and use to get the minimum output amount
                {
                  let slippageTolerance := shr(232, calldataload(pos))
                  mstore(add(tokenInfo, 0xA0), div(mul(outputQuote, sub(0xFFFFFF, slippageTolerance)), 0xFFFFFF))
                }
                pos := add(pos, 3)

                // Load in the executor address
                result, pos := getAddress(pos)
                if eq(result, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE) {
                    let inputPos := shr(240, calldataload(sub(pos, 2)))
                    mstore(add(executorLookup, 0x00), sub(inputPos, 2))
                    mstore(add(executorLookup, 0x20), 1)
                }
                executor := result

                // Load in the destination to send the input to - Zero denotes the executor
                result, pos := getAddress(pos)
                if eq(result, 0) { result := executor }
                mstore(add(tokenInfo, 0x40), result)

                // Load in the destination to send the output to - Zero denotes msg.sender
                result, pos := getAddress(pos)
                if eq(result, 0) { result := msgSender }
                mstore(add(tokenInfo, 0xC0), result)

                // Load in the referralCode
                referralCode := shr(224, calldataload(pos))
                pos := add(pos, 4)

                // Set the offset and size for the pathDefinition portion of the msg.data
                pathDefinition.length := mul(shr(248, calldataload(pos)), 32)
                pathDefinition.offset := add(pos, 1)
            }
        }

        // For inputToken
        if (inputTokenLookup.needsLookup) {
            tokenInfo.inputToken = odosRouter.addressList(inputTokenLookup.tokenIndex);
        }
        
        // For outputToken
        if (outputTokenLookup.needsLookup) {
            tokenInfo.outputToken = odosRouter.addressList(outputTokenLookup.tokenIndex);
        }
        
        // For executor
        if (executorLookup.needsLookup) {
            executor = odosRouter.addressList(executorLookup.tokenIndex);
        }

        addressesFound = abi.encodePacked(tokenInfo.inputToken, tokenInfo.inputReceiver, tokenInfo.outputToken, tokenInfo.outputReceiver, executor); 
    }
} 


interface IOdosRouterV2 {
    function addressList(uint256 index) external view returns (address); 
}

struct Address {    
    uint256 tokenIndex; 
    bool needsLookup; 
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer, DecoderCustomTypes} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";

abstract contract AaveV3DecoderAndSanitizer is BaseDecoderAndSanitizer {
    //============================== AAVEV3 ===============================

    function supply(address asset, uint256, address onBehalfOf, uint16)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(asset, onBehalfOf);
    }

    function withdraw(address asset, uint256, address to) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(asset, to);
    }

    function borrow(address asset, uint256, uint256, uint16, address onBehalfOf)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(asset, onBehalfOf);
    }

    function repay(address asset, uint256, uint256, address onBehalfOf)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(asset, onBehalfOf);
    }

    function setUserUseReserveAsCollateral(address asset, bool)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(asset);
    }

    function setUserEMode(uint8) external pure virtual returns (bytes memory addressesFound) {
        // Nothing to sanitize or return
        return addressesFound;
    }

    function claimRewards(address[] calldata, /*assets*/ uint256, /*amount*/ address to, address /*reward*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(to);
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer, DecoderCustomTypes} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";
import {ERC4626DecoderAndSanitizer} from "src/base/DecodersAndSanitizers/Protocols/ERC4626DecoderAndSanitizer.sol";

abstract contract SiloDecoderAndSanitizer is BaseDecoderAndSanitizer, ERC4626DecoderAndSanitizer {
    //in addition to ERC4626 functions for depositing, these functions can be used
    function deposit(uint256, /*_assets*/ address _receiver, DecoderCustomTypes.CollateralType /*_collateralType*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_receiver);
    }

    function mint(uint256, /*_shares*/ address _receiver, DecoderCustomTypes.CollateralType /*_collateralType*/ )
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_receiver);
    }

    function withdraw(
        uint256, /*_assets*/
        address _receiver,
        address _owner,
        DecoderCustomTypes.CollateralType /*_collateralType*/
    ) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(_receiver, _owner);
    }

    function redeem(
        uint256, /*_shares*/
        address _receiver,
        address _owner,
        DecoderCustomTypes.CollateralType /*_collateralType*/
    ) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(_receiver, _owner);
    }

    function borrow(uint256, /*_assets*/ address _receiver, address _borrower)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_receiver, _borrower);
    }

    function borrowShares(uint256, /*_shares*/ address _receiver, address _borrower)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_receiver, _borrower);
    }

    function borrowSameAsset(uint256, /*_assets*/ address _receiver, address _borrower)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_receiver, _borrower);
    }

    function repay(uint256, /*_assets*/ address _borrower)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_borrower);
    }

    function repayShares(uint256, /*_shares*/ address _borrower)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(_borrower);
    }

    function transitionCollateral(
        uint256, /*_shares*/
        address _owner,
        DecoderCustomTypes.CollateralType /*_transitionFrom*/
    ) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(_owner);
    }

    function switchCollateralToThisSilo() external pure virtual returns (bytes memory addressesFound) {
        return addressesFound;
    }

    function accrueInterest() external pure virtual returns (bytes memory addressesFound) {
        return addressesFound;
    }

    // SILO ROUTER FUNCTIONS

    function execute(DecoderCustomTypes.Action[] memory actions)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        for (uint256 i = 0; i < actions.length; i++) {
            address silo = address(actions[i].silo);
            address asset = address(actions[i].asset);
            addressesFound = abi.encodePacked(silo, asset);
        }
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

contract DecoderCustomTypes {
    // ========================================= BALANCER =========================================
    struct JoinPoolRequest {
        address[] assets;
        uint256[] maxAmountsIn;
        bytes userData;
        bool fromInternalBalance;
    }

    struct ExitPoolRequest {
        address[] assets;
        uint256[] minAmountsOut;
        bytes userData;
        bool toInternalBalance;
    }

    enum SwapKind {
        GIVEN_IN,
        GIVEN_OUT
    }

    struct SingleSwap {
        bytes32 poolId;
        SwapKind kind;
        address assetIn;
        address assetOut;
        uint256 amount;
        bytes userData;
    }

    struct FundManagement {
        address sender;
        bool fromInternalBalance;
        address recipient;
        bool toInternalBalance;
    }

    // ========================================= UNISWAP V3 =========================================

    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    struct ExactInputParamsRouter02 {
        bytes path;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    struct PancakeSwapExactInputParams {
        bytes path;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    // ========================================= MORPHO BLUE =========================================

    struct MarketParams {
        address loanToken;
        address collateralToken;
        address oracle;
        address irm;
        uint256 lltv;
    }

    // ========================================= 1INCH =========================================

    struct SwapDescription {
        address srcToken;
        address dstToken;
        address payable srcReceiver;
        address payable dstReceiver;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 flags;
    }

    // ========================================= PENDLE =========================================
    struct TokenInput {
        // TOKEN DATA
        address tokenIn;
        uint256 netTokenIn;
        address tokenMintSy;
        // AGGREGATOR DATA
        address pendleSwap;
        SwapData swapData;
    }

    struct TokenOutput {
        // TOKEN DATA
        address tokenOut;
        uint256 minTokenOut;
        address tokenRedeemSy;
        // AGGREGATOR DATA
        address pendleSwap;
        SwapData swapData;
    }

    struct ApproxParams {
        uint256 guessMin;
        uint256 guessMax;
        uint256 guessOffchain; // pass 0 in to skip this variable
        uint256 maxIteration; // every iteration, the diff between guessMin and guessMax will be divided by 2
        uint256 eps; // the max eps between the returned result & the correct result, base 1e18. Normally this number will be set
            // to 1e15 (1e18/1000 = 0.1%)
    }

    struct SwapData {
        SwapType swapType;
        address extRouter;
        bytes extCalldata;
        bool needScale;
    }

    enum SwapType {
        NONE,
        KYBERSWAP,
        ONE_INCH,
        // ETH_WETH not used in Aggregator
        ETH_WETH
    }

    struct LimitOrderData {
        address limitRouter;
        uint256 epsSkipMarket; // only used for swap operations, will be ignored otherwise
        FillOrderParams[] normalFills;
        FillOrderParams[] flashFills;
        bytes optData;
    }

    struct FillOrderParams {
        Order order;
        bytes signature;
        uint256 makingAmount;
    }

    struct Order {
        uint256 salt;
        uint256 expiry;
        uint256 nonce;
        OrderType orderType;
        address token;
        address YT;
        address maker;
        address receiver;
        uint256 makingAmount;
        uint256 lnImpliedRate;
        uint256 failSafeRate;
        bytes permit;
    }

    enum OrderType {
        SY_FOR_PT,
        PT_FOR_SY,
        SY_FOR_YT,
        YT_FOR_SY
    }

    // ========================================= EIGEN LAYER =========================================

    struct QueuedWithdrawalParams {
        // Array of strategies that the QueuedWithdrawal contains
        address[] strategies;
        // Array containing the amount of shares in each Strategy in the `strategies` array
        uint256[] shares;
        // The address of the withdrawer
        address withdrawer;
    }

    struct Withdrawal {
        // The address that originated the Withdrawal
        address staker;
        // The address that the staker was delegated to at the time that the Withdrawal was created
        address delegatedTo;
        // The address that can complete the Withdrawal + will receive funds when completing the withdrawal
        address withdrawer;
        // Nonce used to guarantee that otherwise identical withdrawals have unique hashes
        uint256 nonce;
        // Block number when the Withdrawal was created
        uint32 startBlock;
        // Array of strategies that the Withdrawal contains
        address[] strategies;
        // Array containing the amount of shares in each Strategy in the `strategies` array
        uint256[] shares;
    }

    struct SignatureWithExpiry {
        // the signature itself, formatted as a single bytes object
        bytes signature;
        // the expiration timestamp (UTC) of the signature
        uint256 expiry;
    }

    struct EarnerTreeMerkleLeaf {
        address earner;
        bytes32 earnerTokenRoot;
    }

    struct TokenTreeMerkleLeaf {
        address token;
        uint256 cumulativeEarnings;
    }

    struct RewardsMerkleClaim {
        uint32 rootIndex;
        uint32 earnerIndex;
        bytes earnerTreeProof;
        EarnerTreeMerkleLeaf earnerLeaf;
        uint32[] tokenIndices;
        bytes[] tokenTreeProofs;
        TokenTreeMerkleLeaf[] tokenLeaves;
    }

    // ========================================= CCIP =========================================

    // If extraArgs is empty bytes, the default is 200k gas limit.
    struct EVM2AnyMessage {
        bytes receiver; // abi.encode(receiver address) for dest EVM chains
        bytes data; // Data payload
        EVMTokenAmount[] tokenAmounts; // Token transfers
        address feeToken; // Address of feeToken. address(0) means you will send msg.value.
        bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2)
    }

    /// @dev RMN depends on this struct, if changing, please notify the RMN maintainers.
    struct EVMTokenAmount {
        address token; // token address on the local chain.
        uint256 amount; // Amount of tokens.
    }

    struct EVMExtraArgsV1 {
        uint256 gasLimit;
    }

    // ========================================= OFT =========================================

    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.
    }

    struct MessagingFee {
        uint256 nativeFee;
        uint256 lzTokenFee;
    }
    // ========================================= L1StandardBridge =========================================

    struct WithdrawalTransaction {
        uint256 nonce;
        address sender;
        address target;
        uint256 value;
        uint256 gasLimit;
        bytes data;
    }

    struct OutputRootProof {
        bytes32 version;
        bytes32 stateRoot;
        bytes32 messagePasserStorageRoot;
        bytes32 latestBlockhash;
    }

    // ========================================= Mantle L1StandardBridge =========================================

    struct MantleWithdrawalTransaction {
        uint256 nonce;
        address sender;
        address target;
        uint256 mntValue;
        uint256 value;
        uint256 gasLimit;
        bytes data;
    }

    // ========================================= Linea Bridge =========================================

    struct ClaimMessageWithProofParams {
        bytes32[] proof;
        uint256 messageNumber;
        uint32 leafIndex;
        address from;
        address to;
        uint256 fee;
        uint256 value;
        address payable feeRecipient;
        bytes32 merkleRoot;
        bytes data;
    }

    // ========================================= Scroll Bridge =========================================

    struct L2MessageProof {
        uint256 batchIndex;
        bytes merkleProof;
    }

    // ========================================= Camelot V3 =========================================

    struct CamelotMintParams {
        address token0;
        address token1;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }
    // ========================================= Velodrome V3 =========================================

    struct VelodromeMintParams {
        address token0;
        address token1;
        int24 tickSpacing;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
        uint160 sqrtPriceX96;
    }

    // ========================================= Karak =========================================

    struct QueuedWithdrawal {
        address staker;
        address delegatedTo;
        uint256 nonce;
        uint256 start;
        WithdrawRequest request;
    }

    struct WithdrawRequest {
        address[] vaults;
        uint256[] shares;
        address withdrawer;
    }

    // ========================================= Term Finance ==================================

    /// @dev TermAuctionOfferSubmission represents an offer submission to offeror an amount of money for a specific interest rate
    struct TermAuctionOfferSubmission {
        /// @dev For an existing offer this is the unique onchain identifier for this offer. For a new offer this is a randomized input that will be used to generate the unique onchain identifier.
        bytes32 id;
        /// @dev The address of the offeror
        address offeror;
        /// @dev Hash of the offered price as a percentage of the initial loaned amount vs amount returned at maturity. This stores 9 decimal places
        bytes32 offerPriceHash;
        /// @dev The maximum amount of purchase tokens that can be lent
        uint256 amount;
        /// @dev The address of the ERC20 purchase token
        address purchaseToken;
    }

    // ========================================= Dolomite Finance ==================================

    enum BalanceCheckFlag {
        Both,
        From,
        To,
        None
    }

    // ========================================= Silo Finance ==================================
    /// @dev There are 2 types of accounting in the system: for non-borrowable collateral deposit called "protected" and
    ///      for borrowable collateral deposit called "collateral". System does
    ///      identical calculations for each type of accounting but it uses different data. To avoid code duplication
    ///      this enum is used to decide which data should be read.
    enum CollateralType {
        Protected, // default
        Collateral
    }

    enum ActionType {
        Deposit,
        Mint,
        Repay,
        RepayShares
    }

    struct Action {
        // what do you want to do?
        uint8 actionType;
        // which Silo are you interacting with?
        address silo;
        // what asset do you want to use?
        address asset;
        // options specific for actions
        bytes options;
    }

    struct AnyAction {
        // how much assets or shares do you want to use?
        uint256 amount;
        // are you using Protected, Collateral
        uint8 assetType;
    }

    // ========================================= LBTC Bridge ==================================
    struct DepositBridgeAction {
        uint256 fromChain;
        bytes32 fromContract;
        uint256 toChain;
        address toContract;
        address recipient;
        uint64 amount;
        uint256 nonce;
    }

    // ========================================= Odos ==================================
    
    struct swapTokenInfo {
        address inputToken;
        uint256 inputAmount;
        address inputReceiver;
        address outputToken;
        uint256 outputQuote;
        uint256 outputMin;
        address outputReceiver;
    }
    // ========================================= Level ==================================
    
    /// @dev for reference 
    //enum OrderType {
    //    MINT,
    //    REDEEM
    //}
    
    struct LevelOrder {
        uint8 order_type;
        address benefactor;
        address beneficiary;
        address collateral_asset;
        uint256 collateral_amount;
        uint256 lvlusd_amount;
    }    

    struct Route {
        address[] addresses;
        uint256[] ratios;
    }
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.21;

import {BaseDecoderAndSanitizer, DecoderCustomTypes} from "src/base/DecodersAndSanitizers/BaseDecoderAndSanitizer.sol";

abstract contract ERC4626DecoderAndSanitizer is BaseDecoderAndSanitizer {
    //============================== ERC4626 ===============================

    function deposit(uint256, address receiver) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(receiver);
    }

    function mint(uint256, address receiver) external pure virtual returns (bytes memory addressesFound) {
        addressesFound = abi.encodePacked(receiver);
    }

    function withdraw(uint256, address receiver, address owner)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(receiver, owner);
    }

    function redeem(uint256, address receiver, address owner)
        external
        pure
        virtual
        returns (bytes memory addressesFound)
    {
        addressesFound = abi.encodePacked(receiver, owner);
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):