Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x0CBC13B84286007ec4F17CD0f9DC7D7cA6EE4Fff
Balance 0 ETH
Nonce 1
Code Size 4085 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

4085 bytes
0x608060405260043610610041575f3560e01c806316d2a88c1461004c57806341c0e1b51461007b5780638cedca7114610091578063c579d490146100d0575f80fd5b3661004857005b5f80fd5b61005f61005a366004610cd9565b6100ef565b6040805192151583526020830191909152015b60405180910390f35b348015610086575f80fd5b5061008f61025b565b005b34801561009c575f80fd5b506100b873ccf3d848e08b94478ed8f46ffead3008faf581fd81565b6040516001600160a01b039091168152602001610072565b3480156100db575f80fd5b5061008f6100ea366004610dd7565b61031c565b5f805f83610120015160a0015180602001905181019061010f9190610e37565b905061013f846101200151604001518560400151865f01516001600160a01b03166104509092919063ffffffff16565b610155815f015182602001518660400151610553565b60208401515f9061016f906001600160a01b0316306105b0565b9050846101200151602001516001600160a01b0316825f01516040516101959190610ee0565b5f604051808303815f865af19150503d805f81146101ce576040519150601f19603f3d011682016040523d82523d5f602084013e6101d3565b606091505b5050809450505f841561023f57602086015182906101fa906001600160a01b0316306105b0565b6102049190610f0f565b9050805f0361023f576040517f6a756fbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610251865f015187602001513361067c565b9395939450505050565b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b031663f851a4406040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102d99190610f22565b6001600160a01b031614610319576040517fa6c827a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33ff5b336001600160a01b031673ccf3d848e08b94478ed8f46ffead3008faf581fd6001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610376573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061039a9190610f22565b6001600160a01b0316146103da576040517f19494c8a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03831673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee03610437576040516001600160a01b0383169082156108fc029083905f818181858888f19350505050158015610431573d5f803e3d5ffd5b50505050565b61044b6001600160a01b03841683836106c8565b505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663095ea7b360e01b1790526104b68482610711565b610431576040516001600160a01b03841660248201525f604482015261054990859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526107b2565b61043184826107b2565b61055e826020610f44565b83511015610598576040517ff340347200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806105a4602084610f44565b93909301929092525050565b5f7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b038416016105f257506001600160a01b03811631610676565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa15801561064f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106739190610f57565b90505b92915050565b61069c73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee825f1961089d565b506106b26001600160a01b038416825f1961089d565b506104316001600160a01b038316825f1961089d565b6040516001600160a01b03831660248201526044810182905261044b9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016104e5565b5f805f846001600160a01b03168460405161072c9190610ee0565b5f604051808303815f865af19150503d805f8114610765576040519150601f19603f3d011682016040523d82523d5f602084013e61076a565b606091505b50915091508180156107945750805115806107945750808060200190518101906107949190610f6e565b80156107a957505f856001600160a01b03163b115b95945050505050565b5f610806826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166109c99092919063ffffffff16565b905080515f14806108265750808060200190518101906108269190610f6e565b61044b5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5f5f1982036108b3576108b084306105b0565b91505b6001600160a01b038316158015906108d457506001600160a01b0383163014155b80156108df57508115155b156109c2576001600160a01b03841673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee146109215761091c6001600160a01b03851684846106c8565b6109c2565b5f836001600160a01b0316836040515f6040518083038185875af1925050503d805f811461096a576040519150601f19603f3d011682016040523d82523d5f602084013e61096f565b606091505b50509050806109c05760405162461bcd60e51b815260206004820152600d60248201527f4574682073656e64206661696c000000000000000000000000000000000000006044820152606401610894565b505b5092915050565b60606109d784845f856109df565b949350505050565b60606109ea85610ab8565b610a20576040517f304619b500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80866001600160a01b03168587604051610a3b9190610ee0565b5f6040518083038185875af1925050503d805f8114610a75576040519150601f19603f3d011682016040523d82523d5f602084013e610a7a565b606091505b50915091508115610a8e5791506109d79050565b805115610a9e5780518082602001fd5b8360405162461bcd60e51b81526004016108949190610f8d565b5f813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4708181148015906109d7575050151592915050565b634e487b7160e01b5f52604160045260245ffd5b604051610140810167ffffffffffffffff81118282101715610b2857610b28610af0565b60405290565b6040805190810167ffffffffffffffff81118282101715610b2857610b28610af0565b604051601f8201601f1916810167ffffffffffffffff81118282101715610b7a57610b7a610af0565b604052919050565b6001600160a01b0381168114610b96575f80fd5b50565b8035610ba481610b82565b919050565b5f67ffffffffffffffff821115610bc257610bc2610af0565b50601f01601f191660200190565b5f82601f830112610bdf575f80fd5b8135610bf2610bed82610ba9565b610b51565b818152846020838601011115610c06575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60c08284031215610c32575f80fd5b60405160c0810167ffffffffffffffff8282108183111715610c5657610c56610af0565b8160405282935084359150610c6a82610b82565b908252602084013590610c7c82610b82565b81602084015260408501359150610c9282610b82565b816040840152606085013560608401526080850135608084015260a0850135915080821115610cbf575f80fd5b50610ccc85828601610bd0565b60a0830152505092915050565b5f60208284031215610ce9575f80fd5b813567ffffffffffffffff80821115610d00575f80fd5b908301906101408286031215610d14575f80fd5b610d1c610b04565b610d2583610b99565b8152610d3360208401610b99565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a0820152610d6c60c08401610b99565b60c0820152610d7d60e08401610b99565b60e08201526101008084013583811115610d95575f80fd5b610da188828701610bd0565b8284015250506101208084013583811115610dba575f80fd5b610dc688828701610c22565b918301919091525095945050505050565b5f805f60608486031215610de9575f80fd5b8335610df481610b82565b92506020840135610e0481610b82565b929592945050506040919091013590565b5f5b83811015610e2f578181015183820152602001610e17565b50505f910152565b5f6020808385031215610e48575f80fd5b825167ffffffffffffffff80821115610e5f575f80fd5b9084019060408287031215610e72575f80fd5b610e7a610b2e565b825182811115610e88575f80fd5b83019150601f82018713610e9a575f80fd5b8151610ea8610bed82610ba9565b8181528886838601011115610ebb575f80fd5b610eca82878301888701610e15565b8252509183015192820192909252949350505050565b5f8251610ef1818460208701610e15565b9190910192915050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561067657610676610efb565b5f60208284031215610f32575f80fd5b8151610f3d81610b82565b9392505050565b8082018082111561067657610676610efb565b5f60208284031215610f67575f80fd5b5051919050565b5f60208284031215610f7e575f80fd5b81518015158114610f3d575f80fd5b602081525f8251806020840152610fab816040850160208701610e15565b601f01601f1916919091016040019291505056fea2646970667358221220ab310f5cdc40995ddd73051f90a3c408618a33b26825f821362050b75ff8e6ce64736f6c63430008180033

Verified Source Code Partial Match

Compiler: v0.8.24+commit.e11b9ed9 EVM: shanghai Optimization: Yes (1000 runs)
OdosWrapper.sol 607 lines
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;










contract MainnetAuthAddresses {
    address internal constant ADMIN_VAULT_ADDR = 0xCCf3d848e08b94478Ed8f46fFead3008faF581fD;
    address internal constant DSGUARD_FACTORY_ADDRESS = 0x5a15566417e6C1c9546523066500bDDBc53F88C7;
    address internal constant ADMIN_ADDR = 0x25eFA336886C74eA8E282ac466BdCd0199f85BB9; // USED IN ADMIN VAULT CONSTRUCTOR
    address internal constant PROXY_AUTH_ADDRESS = 0x149667b6FAe2c63D1B4317C716b0D0e4d3E2bD70;
    address internal constant MODULE_AUTH_ADDRESS = 0x7407974DDBF539e552F1d051e44573090912CC3D;
}







contract AuthHelper is MainnetAuthAddresses {
}








contract AdminVault is AuthHelper {
    address public owner;
    address public admin;

    error SenderNotAdmin();

    constructor() {
        owner = msg.sender;
        admin = ADMIN_ADDR;
    }

    /// @notice Admin is able to change owner
    /// @param _owner Address of new owner
    function changeOwner(address _owner) public {
        if (admin != msg.sender){
            revert SenderNotAdmin();
        }
        owner = _owner;
    }

    /// @notice Admin is able to set new admin
    /// @param _admin Address of multisig that becomes new admin
    function changeAdmin(address _admin) public {
        if (admin != msg.sender){
            revert SenderNotAdmin();
        }
        admin = _admin;
    }

}







interface IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint256 digits);
    function totalSupply() external view returns (uint256 supply);

    function balanceOf(address _owner) external view returns (uint256 balance);

    function transfer(address _to, uint256 _value) external returns (bool success);

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) external returns (bool success);

    function approve(address _spender, uint256 _value) external returns (bool success);

    function allowance(address _owner, address _spender) external view returns (uint256 remaining);

    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}







library Address {
    //insufficient balance
    error InsufficientBalance(uint256 available, uint256 required);
    //unable to send value, recipient may have reverted
    error SendingValueFail();
    //insufficient balance for call
    error InsufficientBalanceForCall(uint256 available, uint256 required);
    //call to non-contract
    error NonContractCall();
    
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            codehash := extcodehash(account)
        }
        return (codehash != accountHash && codehash != 0x0);
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        uint256 balance = address(this).balance;
        if (balance < amount){
            revert InsufficientBalance(balance, amount);
        }

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{value: amount}("");
        if (!(success)){
            revert SendingValueFail();
        }
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        uint256 balance = address(this).balance;
        if (balance < value){
            revert InsufficientBalanceForCall(balance, value);
        }
        return _functionCallWithValue(target, data, value, errorMessage);
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        if (!(isContract(target))){
            revert NonContractCall();
        }

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: weiValue}(data);
        if (success) {
            return returndata;
        } else {
            // 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}











library SafeERC20 {
    using Address for address;

    /**
     * @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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

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

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, 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, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * 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;
    }
}











contract AdminAuth is AuthHelper {
    using SafeERC20 for IERC20;

    AdminVault public constant adminVault = AdminVault(ADMIN_VAULT_ADDR);

    error SenderNotOwner();
    error SenderNotAdmin();

    modifier onlyOwner() {
        if (adminVault.owner() != msg.sender){
            revert SenderNotOwner();
        }
        _;
    }

    modifier onlyAdmin() {
        if (adminVault.admin() != msg.sender){
            revert SenderNotAdmin();
        }
        _;
    }

    /// @notice withdraw stuck funds
    function withdrawStuckFunds(address _token, address _receiver, uint256 _amount) public onlyOwner {
        if (_token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
            payable(_receiver).transfer(_amount);
        } else {
            IERC20(_token).safeTransfer(_receiver, _amount);
        }
    }

    /// @notice Destroy the contract
    /// @dev Deprecated method, selfdestruct will soon just send eth
    function kill() public onlyAdmin {
        selfdestruct(payable(msg.sender));
    }
}







abstract contract IWETH {
    function allowance(address, address) public virtual view returns (uint256);

    function balanceOf(address) public virtual view returns (uint256);

    function approve(address, uint256) public virtual;

    function transfer(address, uint256) public virtual returns (bool);

    function transferFrom(
        address,
        address,
        uint256
    ) public virtual returns (bool);

    function deposit() public payable virtual;

    function withdraw(uint256) public virtual;
}









library TokenUtils {
    using SafeERC20 for IERC20;

    address public constant WETH_ADDR = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    address public constant ETH_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    /// @dev Only approves the amount if allowance is lower than amount, does not decrease allowance
    function approveToken(
        address _tokenAddr,
        address _to,
        uint256 _amount
    ) internal {
        if (_tokenAddr == ETH_ADDR) return;

        if (IERC20(_tokenAddr).allowance(address(this), _to) < _amount) {
            IERC20(_tokenAddr).safeApprove(_to, _amount);
        }
    }

    function pullTokensIfNeeded(
        address _token,
        address _from,
        uint256 _amount
    ) internal returns (uint256) {
        // handle max uint amount
        if (_amount == type(uint256).max) {
            _amount = getBalance(_token, _from);
        }

        if (_from != address(0) && _from != address(this) && _token != ETH_ADDR && _amount != 0) {
            IERC20(_token).safeTransferFrom(_from, address(this), _amount);
        }

        return _amount;
    }

    function withdrawTokens(
        address _token,
        address _to,
        uint256 _amount
    ) internal returns (uint256) {
        if (_amount == type(uint256).max) {
            _amount = getBalance(_token, address(this));
        }

        if (_to != address(0) && _to != address(this) && _amount != 0) {
            if (_token != ETH_ADDR) {
                IERC20(_token).safeTransfer(_to, _amount);
            } else {
                (bool success, ) = _to.call{value: _amount}("");
                require(success, "Eth send fail");
            }
        }

        return _amount;
    }

    function depositWeth(uint256 _amount) internal {
        IWETH(WETH_ADDR).deposit{value: _amount}();
    }

    function withdrawWeth(uint256 _amount) internal {
        IWETH(WETH_ADDR).withdraw(_amount);
    }

    function getBalance(address _tokenAddr, address _acc) internal view returns (uint256) {
        if (_tokenAddr == ETH_ADDR) {
            return _acc.balance;
        } else {
            return IERC20(_tokenAddr).balanceOf(_acc);
        }
    }

    function getTokenDecimals(address _token) internal view returns (uint256) {
        if (_token == ETH_ADDR) return 18;

        return IERC20(_token).decimals();
    }
}









contract DFSExchangeHelper {
    
    using TokenUtils for address;
    
    error InvalidOffchainData();
    error OutOfRangeSlicingError();
    //Order success but amount 0
    error ZeroTokensSwapped();

    using SafeERC20 for IERC20;

    function sendLeftover(
        address _srcAddr,
        address _destAddr,
        address payable _to
    ) internal {
        // clean out any eth leftover
        TokenUtils.ETH_ADDR.withdrawTokens(_to, type(uint256).max);

        _srcAddr.withdrawTokens(_to, type(uint256).max);
        _destAddr.withdrawTokens(_to, type(uint256).max);
    }

    function sliceUint(bytes memory bs, uint256 start) internal pure returns (uint256) {
        if (bs.length < start + 32){
            revert OutOfRangeSlicingError();
        }

        uint256 x;
        assembly {
            x := mload(add(bs, add(0x20, start)))
        }

        return x;
    }

    function writeUint256(
        bytes memory _b,
        uint256 _index,
        uint256 _input
    ) internal pure {
        if (_b.length < _index + 32) {
            revert InvalidOffchainData();
        }

        bytes32 input = bytes32(_input);

        _index += 32;

        // Read the bytes32 from array memory
        assembly {
            mstore(add(_b, _index), input)
        }
    }
}






contract DFSExchangeData {

    struct OffchainData {
        address wrapper; // dfs wrapper address for the aggregator (must be in WrapperExchangeRegistry)
        address exchangeAddr; // exchange address we are calling to execute the order (must be in ExchangeAggregatorRegistry)
        address allowanceTarget; // exchange aggregator contract we give allowance to
        uint256 price; // expected price that the aggregator sent us
        uint256 protocolFee; // deprecated (used as a separate fee amount for 0x v1)
        bytes callData; // 0ff-chain calldata the aggregator gives to perform the swap
    }

    struct ExchangeData {
        address srcAddr; // source token address (which we're selling)
        address destAddr; // destination token address (which we're buying)
        uint256 srcAmount; // amount of source token in token decimals
        uint256 destAmount; // amount of bought token in token decimals
        uint256 minPrice; // minPrice we are expecting (checked in DFSExchangeCore)
        uint256 dfsFeeDivider; // service fee divider
        address user; // currently deprecated (used to check custom fees for the user)
        address wrapper; // on-chain wrapper address (must be in WrapperExchangeRegistry)
        bytes wrapperData; // on-chain additional data for on-chain (uniswap route for example)
        OffchainData offchainData; // offchain aggregator order
    }
}







abstract contract IOffchainWrapper is DFSExchangeData {
    function takeOrder(
        ExchangeData memory _exData
    ) virtual public payable returns (bool success, uint256);
}













contract OdosWrapper is IOffchainWrapper, DFSExchangeHelper, AdminAuth {

    using TokenUtils for address;
    using SafeERC20 for IERC20;

    /// @notice offchainData.callData should be this struct encoded
    struct OdosCalldata{
        bytes realCalldata;
        uint256 offset;
    }

    /// @notice Takes order from Odos and returns bool indicating if it is successful
    /// @param _exData Exchange data
    function takeOrder(
        ExchangeData memory _exData
    ) override public payable returns (bool success, uint256) {
        OdosCalldata memory odosCalldata = abi.decode(_exData.offchainData.callData, (OdosCalldata));

        // approve odos allowance contract
        IERC20(_exData.srcAddr).safeApprove(_exData.offchainData.allowanceTarget, _exData.srcAmount);

        // write in the exact amount we are selling/buying in an order
        writeUint256(odosCalldata.realCalldata, odosCalldata.offset, _exData.srcAmount);

        uint256 tokensBefore = _exData.destAddr.getBalance(address(this));

        /// @dev the amount of tokens received is checked in DFSExchangeCore
        /// @dev Exchange wrapper contracts should not be used on their own
        (success, ) = _exData.offchainData.exchangeAddr.call(odosCalldata.realCalldata);
        uint256 tokensSwapped = 0;

        if (success) {
            // get the current balance of the swapped tokens
            tokensSwapped = _exData.destAddr.getBalance(address(this)) - tokensBefore;
            if (tokensSwapped == 0){
                revert ZeroTokensSwapped();
            }
        }

        // returns all funds from src addr, dest addr and eth funds (protocol fee leftovers)
        sendLeftover(_exData.srcAddr, _exData.destAddr, payable(msg.sender));

        return (success, tokensSwapped);
    }

    // solhint-disable-next-line no-empty-blocks
    receive() external virtual payable {}
}

Read Contract

adminVault 0x8cedca71 → address

Write Contract 3 functions

These functions modify contract state and require a wallet transaction to execute.

kill 0x41c0e1b5
No parameters
takeOrder 0xdecd9c4f
tuple _exData
returns: bool, uint256
withdrawStuckFunds 0xc579d490
address _token
address _receiver
uint256 _amount

Token Balances (1)

View Transfers →
stETH 0

Recent Transactions

No transactions found for this address