Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
BladePermitRouter
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 800 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED // Copyright 2023 Shipyard Software, Inc. pragma solidity ^0.8.20; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol"; import { IBladeExchange } from "./interfaces/IBladeExchange.sol"; import { Signature } from "./types/BladeTypes.sol"; interface IDaiLikePermit { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; } contract BladePermitRouter is ReentrancyGuard { using SafeERC20 for IERC20; address immutable BLADE_POOL; constructor(address _blade_pool) { BLADE_POOL = _blade_pool; } function permit_swap(address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData, bytes calldata permit) public { safePermit(inputToken, permit); IERC20(inputToken).safeTransferFrom(msg.sender, BLADE_POOL, inputAmount); if(outputToken == address(0)) { IBladeExchange(BLADE_POOL).sellTokenForEth(inputToken, inputAmount, outputAmount, goodUntil, destinationAddress, theSignature, auxiliaryData); } else { IBladeExchange(BLADE_POOL).swap(inputToken, outputToken, inputAmount, outputAmount, goodUntil, destinationAddress, theSignature, auxiliaryData); } } function permit_depositSingleAsset( address depositor, address inputToken, uint256 inputAmount, uint256 lockTime, uint256 poolTokens, uint256 goodUntil, Signature calldata theSignature, bytes calldata extraData, bytes calldata permit ) public { safePermit(inputToken, permit); IERC20(inputToken).safeTransferFrom(msg.sender, BLADE_POOL, inputAmount); IBladeExchange(BLADE_POOL).depositSingleAsset(depositor, inputToken, inputAmount, lockTime, poolTokens, goodUntil, theSignature, extraData); } function safePermit(address token, bytes calldata permit) internal { bool success; if (permit.length == 32 * 7) { success = _makeCalldataCall(token, IERC20Permit.permit.selector, permit); } else if (permit.length == 32 * 8) { success = _makeCalldataCall(token, IDaiLikePermit.permit.selector, permit); } else { revert("bad permit length"); } if (!success) { revert("permit failed"); } } function _makeCalldataCall( address token, bytes4 selector, bytes calldata args ) private returns (bool success) { /// @solidity memory-safe-assembly assembly { // solhint-disable-line no-inline-assembly let len := add(4, args.length) let data := mload(0x40) mstore(data, selector) calldatacopy(add(data, 0x04), args.offset, args.length) success := call(gas(), token, 0, data, len, 0x0, 0x20) if success { switch returndatasize() case 0 { success := gt(extcodesize(token), 0) } default { success := and(gt(returndatasize(), 31), eq(mload(0), 1)) } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[ERC-2612]. * * Adds the {permit} method, which can be used to change an account's ERC-20 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 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 { /** * @dev An operation with an ERC-20 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 Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(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. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ 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. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ 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. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ 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 Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { 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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { 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 silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import { Signature } from "../types/BladeTypes.sol"; /// @title Blade Exchange Interface /// @notice Shared interface for all Blade exchange implementations interface IBladeExchange { event Swapped( address indexed inAsset, address indexed outAsset, address indexed recipient, uint256 inAmount, uint256 outAmount, bytes auxiliaryData ); event Deposited( address indexed depositor, uint256 poolTokens, uint256 lockTime ); event Withdrawn( address indexed withdrawer, uint256 poolTokens, uint256 fractionOfPool ); event AssetWithdrawn( address indexed withdrawer, uint256 poolTokens, address indexed assetAddress, uint256 assetAmount ); event FeesTaken( uint256 entitledFeesInDollars, uint256 averagePoolBalanceInDollars, uint256 tokensTransferred ); event TriageAddressChanged(address indexed newAddress); event MarketHalted(address indexed by); event MarketResumed(address indexed by); function WRAPPER_CONTRACT() external view returns (address); function tokenAt(uint index) external view returns (address); function nTokens() external view returns (uint); function isToken(address token) external view returns (bool); function burnToWithdraw(uint256 amount) external; function sellEthForToken( address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData ) external payable; function sellTokenForEth( address inputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData ) external; function transmitAndSellTokenForEth( address inputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData ) external; function transmitAndSwap( address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData ) external; function swap( address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData ) external; function transmitAndDepositSingleAsset( address inputToken, uint256 inputAmount, uint256 lockTime, uint256 poolTokens, uint256 goodUntil, Signature calldata theSignature, bytes calldata extraData ) external; function deposit( address depositor, uint256[] calldata depositAmounts, uint256 lockTime, uint256 poolTokens, uint256 goodUntil, Signature calldata theSignature, bytes calldata extraData ) external payable; function depositSingleAsset( address depositor, address inputToken, uint256 inputAmount, uint256 lockTime, uint256 poolTokens, uint256 goodUntil, Signature calldata theSignature, bytes calldata extraData ) external payable; function withdrawSingleAsset( address tokenHolder, uint256 poolTokenAmountToBurn, address assetAddress, uint256 assetAmount, uint256 goodUntil, Signature calldata theSignature, bytes calldata extraData ) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.20; struct Signature { uint8 v; bytes32 r; bytes32 s; } struct Deposit { uint lockedUntil; uint256 poolTokenAmount; } struct UtilStruct { uint256 qX; uint256 qY; uint256 decimalMultiplierX; uint256 decimalMultiplierY; }
{ "evmVersion": "paris", "libraries": {}, "metadata": { "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 800 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_blade_pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"lockTime","type":"uint256"},{"internalType":"uint256","name":"poolTokens","type":"uint256"},{"internalType":"uint256","name":"goodUntil","type":"uint256"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Signature","name":"theSignature","type":"tuple"},{"internalType":"bytes","name":"extraData","type":"bytes"},{"internalType":"bytes","name":"permit","type":"bytes"}],"name":"permit_depositSingleAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"outputAmount","type":"uint256"},{"internalType":"uint256","name":"goodUntil","type":"uint256"},{"internalType":"address","name":"destinationAddress","type":"address"},{"components":[{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct Signature","name":"theSignature","type":"tuple"},{"internalType":"bytes","name":"auxiliaryData","type":"bytes"},{"internalType":"bytes","name":"permit","type":"bytes"}],"name":"permit_swap","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b5060405161089e38038061089e83398101604081905261002f91610045565b60016000556001600160a01b0316608052610075565b60006020828403121561005757600080fd5b81516001600160a01b038116811461006e57600080fd5b9392505050565b6080516107f46100aa60003960008181607e0152818160ba01528181610159015281816101a3015261023401526107f46000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632d08a1b01461003b578063865be6b314610050575b600080fd5b61004e610049366004610518565b610063565b005b61004e61005e3660046105ec565b61013e565b61006e8a8383610286565b6100a36001600160a01b038b16337f00000000000000000000000000000000000000000000000000000000000000008c610368565b604051632db7a6e760e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635b6f4dce906100ff908e908e908e908e908e908e908e908e908e906004016106aa565b600060405180830381600087803b15801561011957600080fd5b505af115801561012d573d6000803e3d6000fd5b505050505050505050505050505050565b6101498b8383610286565b61017e6001600160a01b038c16337f00000000000000000000000000000000000000000000000000000000000000008c610368565b6001600160a01b038a1661021d5760405163132da19360e21b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634cb6864c906101e6908e908d908d908d908d908d908d908d90600401610713565b600060405180830381600087803b15801561020057600080fd5b505af1158015610214573d6000803e3d6000fd5b50505050610279565b604051630ad9469b60e21b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632b651a6c906100ff908e908e908e908e908e908e908e908e908e90600401610775565b5050505050505050505050565b600060e08290036102ab576102a48463d505accf60e01b85856103d7565b9050610315565b6101008290036102c8576102a4846323f2ebc360e21b85856103d7565b60405162461bcd60e51b815260206004820152601160248201527f626164207065726d6974206c656e67746800000000000000000000000000000060448201526064015b60405180910390fd5b806103625760405162461bcd60e51b815260206004820152600d60248201527f7065726d6974206661696c656400000000000000000000000000000000000000604482015260640161030c565b50505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b17905261036290859061042a565b6000816004016040518581528385600483013760206000838360008b5af1925050508015610422573d801561041857600160005114601f3d11169150610420565b6000863b1191505b505b949350505050565b600080602060008451602086016000885af18061044d576040513d6000823e3d81fd5b50506000513d91508115610465578060011415610472565b6001600160a01b0384163b155b1561036257604051635274afe760e01b81526001600160a01b038516600482015260240161030c565b80356001600160a01b03811681146104b257600080fd5b919050565b6000606082840312156104c957600080fd5b50919050565b60008083601f8401126104e157600080fd5b50813567ffffffffffffffff8111156104f957600080fd5b60208301915083602082850101111561051157600080fd5b9250929050565b60008060008060008060008060008060006101608c8e03121561053a57600080fd5b6105438c61049b565b9a5061055160208d0161049b565b995060408c0135985060608c0135975060808c0135965060a08c0135955061057c8d60c08e016104b7565b94506101208c013567ffffffffffffffff81111561059957600080fd5b6105a58e828f016104cf565b9095509350506101408c013567ffffffffffffffff8111156105c657600080fd5b6105d28e828f016104cf565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060008060006101608c8e03121561060e57600080fd5b6106178c61049b565b9a5061062560208d0161049b565b995060408c0135985060608c0135975060808c0135965061064860a08d0161049b565b955061057c8d60c08e016104b7565b803560ff811680821461066957600080fd5b83525060208181013590830152604090810135910152565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038a1681526001600160a01b03891660208201528760408201528660608201528560808201528460a08201526106ea60c0820185610657565b610140610120820152600061070461014083018486610681565b9b9a5050505050505050505050565b6001600160a01b03891681528760208201528660408201528560608201526001600160a01b038516608082015261074d60a0820185610657565b610120610100820152600061076761012083018486610681565b9a9950505050505050505050565b6001600160a01b038a1681526001600160a01b03891660208201528760408201528660608201528560808201526001600160a01b03851660a08201526106ea60c082018561065756fea2646970667358221220f2e096e4f779c0242b712a63a98c85feff2f2122ee21303e9bece2bacefb991664736f6c634300081c00330000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100365760003560e01c80632d08a1b01461003b578063865be6b314610050575b600080fd5b61004e610049366004610518565b610063565b005b61004e61005e3660046105ec565b61013e565b61006e8a8383610286565b6100a36001600160a01b038b16337f0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d8c610368565b604051632db7a6e760e11b81526001600160a01b037f0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d1690635b6f4dce906100ff908e908e908e908e908e908e908e908e908e906004016106aa565b600060405180830381600087803b15801561011957600080fd5b505af115801561012d573d6000803e3d6000fd5b505050505050505050505050505050565b6101498b8383610286565b61017e6001600160a01b038c16337f0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d8c610368565b6001600160a01b038a1661021d5760405163132da19360e21b81526001600160a01b037f0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d1690634cb6864c906101e6908e908d908d908d908d908d908d908d90600401610713565b600060405180830381600087803b15801561020057600080fd5b505af1158015610214573d6000803e3d6000fd5b50505050610279565b604051630ad9469b60e21b81526001600160a01b037f0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d1690632b651a6c906100ff908e908e908e908e908e908e908e908e908e90600401610775565b5050505050505050505050565b600060e08290036102ab576102a48463d505accf60e01b85856103d7565b9050610315565b6101008290036102c8576102a4846323f2ebc360e21b85856103d7565b60405162461bcd60e51b815260206004820152601160248201527f626164207065726d6974206c656e67746800000000000000000000000000000060448201526064015b60405180910390fd5b806103625760405162461bcd60e51b815260206004820152600d60248201527f7065726d6974206661696c656400000000000000000000000000000000000000604482015260640161030c565b50505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b17905261036290859061042a565b6000816004016040518581528385600483013760206000838360008b5af1925050508015610422573d801561041857600160005114601f3d11169150610420565b6000863b1191505b505b949350505050565b600080602060008451602086016000885af18061044d576040513d6000823e3d81fd5b50506000513d91508115610465578060011415610472565b6001600160a01b0384163b155b1561036257604051635274afe760e01b81526001600160a01b038516600482015260240161030c565b80356001600160a01b03811681146104b257600080fd5b919050565b6000606082840312156104c957600080fd5b50919050565b60008083601f8401126104e157600080fd5b50813567ffffffffffffffff8111156104f957600080fd5b60208301915083602082850101111561051157600080fd5b9250929050565b60008060008060008060008060008060006101608c8e03121561053a57600080fd5b6105438c61049b565b9a5061055160208d0161049b565b995060408c0135985060608c0135975060808c0135965060a08c0135955061057c8d60c08e016104b7565b94506101208c013567ffffffffffffffff81111561059957600080fd5b6105a58e828f016104cf565b9095509350506101408c013567ffffffffffffffff8111156105c657600080fd5b6105d28e828f016104cf565b915080935050809150509295989b509295989b9093969950565b60008060008060008060008060008060006101608c8e03121561060e57600080fd5b6106178c61049b565b9a5061062560208d0161049b565b995060408c0135985060608c0135975060808c0135965061064860a08d0161049b565b955061057c8d60c08e016104b7565b803560ff811680821461066957600080fd5b83525060208181013590830152604090810135910152565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038a1681526001600160a01b03891660208201528760408201528660608201528560808201528460a08201526106ea60c0820185610657565b610140610120820152600061070461014083018486610681565b9b9a5050505050505050505050565b6001600160a01b03891681528760208201528660408201528560608201526001600160a01b038516608082015261074d60a0820185610657565b610120610100820152600061076761012083018486610681565b9a9950505050505050505050565b6001600160a01b038a1681526001600160a01b03891660208201528760408201528660608201528560808201526001600160a01b03851660a08201526106ea60c082018561065756fea2646970667358221220f2e096e4f779c0242b712a63a98c85feff2f2122ee21303e9bece2bacefb991664736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d
-----Decoded View---------------
Arg [0] : _blade_pool (address): 0x5699698aee5624410c1BE3aB6c15dE0999dCbC9d
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005699698aee5624410c1be3ab6c15de0999dcbc9d
Loading...
Loading
Loading...
Loading

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