Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PendleSYDeposit
Compiler Version
v0.8.29+commit.ab55807c
Optimization Enabled:
Yes with 200 runs
Other Settings:
osaka EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ActionBase} from "../dfs/ActionBase.sol";
import {TokenUtils} from "../dfs/TokenUtils.sol";
interface IPendleActionStandardizedYield {
function deposit(address receiver, address tokenIn, uint256 amountTokenToDeposit, uint256 minSharesOut)
external
payable
returns (uint256 amountSharesOut);
}
/// @title PendleSYDeposit - Deposits underlying token into a Pendle SY and returns SY shares
contract PendleSYDeposit is ActionBase {
using TokenUtils for address;
/// @param syToken Address of the SY token
/// @param tokenIn Address of the underlying token to deposit
/// @param amountTokenToDeposit Amount of underlying to deposit
/// @param minSharesOut Minimum SY shares expected
/// @param receiver Address receiving the SY shares
struct Params {
address syToken;
address tokenIn;
uint256 amountTokenToDeposit;
uint256 minSharesOut;
address receiver;
}
/// @inheritdoc ActionBase
function executeAction(
bytes memory _callData,
bytes32[] memory _subData,
uint8[] memory _paramMapping,
bytes32[] memory _returnValues
) public payable virtual override returns (bytes32) {
Params memory inputData = _resolveParams(_callData, _subData, _paramMapping, _returnValues);
uint256 sharesOut = _depositSy(inputData);
emit ActionEvent("PendleSYDeposit", abi.encode(inputData, sharesOut));
return bytes32(sharesOut);
}
/// @inheritdoc ActionBase
function executeActionDirect(bytes memory _callData) public payable override {
Params memory inputData = parseInputs(_callData);
uint256 sharesOut = _depositSy(inputData);
emit ActionEvent("PendleSYDeposit", abi.encode(inputData, sharesOut));
}
/// @inheritdoc ActionBase
function actionType() public pure override returns (uint8) {
return uint8(ActionType.STANDARD_ACTION);
}
function _depositSy(Params memory params) internal returns (uint256) {
params.tokenIn.approveToken(params.syToken, params.amountTokenToDeposit);
uint256 sharesOut = IPendleActionStandardizedYield(params.syToken)
.deposit(params.receiver, params.tokenIn, params.amountTokenToDeposit, params.minSharesOut);
params.tokenIn.approveToken(params.syToken, 0);
return sharesOut;
}
function _resolveParams(
bytes memory _callData,
bytes32[] memory _subData,
uint8[] memory _paramMapping,
bytes32[] memory _returnValues
) internal view returns (Params memory inputData) {
inputData = parseInputs(_callData);
inputData.syToken = _parseParamAddr(inputData.syToken, _paramMapping[0], _subData, _returnValues);
inputData.tokenIn = _parseParamAddr(inputData.tokenIn, _paramMapping[1], _subData, _returnValues);
inputData.amountTokenToDeposit =
_parseParamUint(inputData.amountTokenToDeposit, _paramMapping[2], _subData, _returnValues);
inputData.minSharesOut = _parseParamUint(inputData.minSharesOut, _paramMapping[3], _subData, _returnValues);
inputData.receiver = _parseParamAddr(inputData.receiver, _paramMapping[4], _subData, _returnValues);
}
function parseInputs(bytes memory _callData) public pure returns (Params memory params) {
params = abi.decode(_callData, (Params));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {ActionsUtilHelper} from "./ActionsUtilHelper.sol";
import {SmartWalletUtils} from "./SmartWalletUtils.sol";
/// @title Minimal ActionBase (DefiSaver-like) for local actions
abstract contract ActionBase is ActionsUtilHelper, SmartWalletUtils {
event ActionEvent(string indexed logName, bytes data);
error SubIndexValueError();
error ReturnIndexValueError();
uint8 public constant SUB_MIN_INDEX_VALUE = 128;
uint8 public constant SUB_MAX_INDEX_VALUE = 255;
uint8 public constant RETURN_MIN_INDEX_VALUE = 1;
uint8 public constant RETURN_MAX_INDEX_VALUE = 127;
uint8 public constant NO_PARAM_MAPPING = 0;
enum ActionType {
FL_ACTION,
STANDARD_ACTION,
FEE_ACTION,
CHECK_ACTION,
CUSTOM_ACTION
}
function executeAction(
bytes memory _callData,
bytes32[] memory _subData,
uint8[] memory _paramMapping,
bytes32[] memory _returnValues
) public payable virtual returns (bytes32);
function executeActionDirect(bytes memory _callData) public payable virtual;
function actionType() public pure virtual returns (uint8);
function _parseParamUint(uint256 _param, uint8 _mapType, bytes32[] memory _subData, bytes32[] memory _returnValues)
internal
pure
returns (uint256)
{
if (isReplaceable(_mapType)) {
if (isReturnInjection(_mapType)) {
_param = uint256(_returnValues[getReturnIndex(_mapType)]);
} else {
_param = uint256(_subData[getSubIndex(_mapType)]);
}
}
return _param;
}
function _parseParamAddr(address _param, uint8 _mapType, bytes32[] memory _subData, bytes32[] memory _returnValues)
internal
view
returns (address)
{
if (isReplaceable(_mapType)) {
if (isReturnInjection(_mapType)) {
_param = address(bytes20((_returnValues[getReturnIndex(_mapType)])));
} else {
if (_mapType == 254) return address(this);
if (_mapType == 255) return _fetchOwnerOrWallet(address(this));
_param = address(uint160(uint256(_subData[getSubIndex(_mapType)])));
}
}
return _param;
}
function _parseParamABytes32(
bytes32 _param,
uint8 _mapType,
bytes32[] memory _subData,
bytes32[] memory _returnValues
) internal pure returns (bytes32) {
if (isReplaceable(_mapType)) {
if (isReturnInjection(_mapType)) {
_param = (_returnValues[getReturnIndex(_mapType)]);
} else {
_param = _subData[getSubIndex(_mapType)];
}
}
return _param;
}
function isReplaceable(uint8 _type) internal pure returns (bool) {
return _type != NO_PARAM_MAPPING;
}
function isReturnInjection(uint8 _type) internal pure returns (bool) {
return (_type >= RETURN_MIN_INDEX_VALUE) && (_type <= RETURN_MAX_INDEX_VALUE);
}
function getReturnIndex(uint8 _type) internal pure returns (uint8) {
if (!(isReturnInjection(_type))) {
revert SubIndexValueError();
}
return (_type - RETURN_MIN_INDEX_VALUE);
}
function getSubIndex(uint8 _type) internal pure returns (uint8) {
if (_type < SUB_MIN_INDEX_VALUE) {
revert ReturnIndexValueError();
}
return (_type - SUB_MIN_INDEX_VALUE);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
library TokenUtils {
using SafeERC20 for IERC20;
address internal constant ETH_ADDR = address(0);
function approveToken(address token, address spender, uint256 amount) internal {
if (token == ETH_ADDR) return;
IERC20 erc = IERC20(token);
erc.forceApprove(spender, 0);
erc.forceApprove(spender, amount);
}
function pullTokensIfNeeded(address token, address from, uint256 amount) internal {
if (token == ETH_ADDR || amount == 0) return;
IERC20(token).safeTransferFrom(from, address(this), amount);
}
function withdrawTokens(address token, address to, uint256 amount) internal {
if (amount == 0) return;
if (token == ETH_ADDR) {
payable(to).transfer(amount);
} else {
IERC20(token).safeTransfer(to, amount);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
abstract contract ActionsUtilHelper {
// reserved for future helpers
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
abstract contract SmartWalletUtils {
function _fetchOwnerOrWallet(address wallet) internal view returns (address owner) {
(bool ok, bytes memory data) = wallet.staticcall(abi.encodeWithSignature("owner()"));
if (ok && data.length >= 32) {
owner = abi.decode(data, (address));
} else {
owner = wallet;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @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.5.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 {
if (!_safeTransfer(token, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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 {
if (!_safeTransferFrom(token, from, to, value, true)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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 _safeTransfer(token, to, value, false);
}
/**
* @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 _safeTransferFrom(token, from, to, value, false);
}
/**
* @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 {
if (!_safeApprove(token, spender, value, false)) {
if (!_safeApprove(token, spender, 0, true)) revert SafeERC20FailedOperation(address(token));
if (!_safeApprove(token, spender, value, true)) revert SafeERC20FailedOperation(address(token));
}
}
/**
* @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 relies 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 relies 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}.
* Oppositely, 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 `token.transfer(to, value)` call, 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 to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransfer(IERC20 token, address to, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.transfer.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(to, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
/**
* @dev Imitates a Solidity `token.transferFrom(from, to, value)` call, 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 from The sender of the tokens
* @param to The recipient of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value,
bool bubble
) private returns (bool success) {
bytes4 selector = IERC20.transferFrom.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(from, shr(96, not(0))))
mstore(0x24, and(to, shr(96, not(0))))
mstore(0x44, value)
success := call(gas(), token, 0, 0x00, 0x64, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
mstore(0x60, 0)
}
}
/**
* @dev Imitates a Solidity `token.approve(spender, value)` call, 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 spender The spender of the tokens
* @param value The amount of token to transfer
* @param bubble Behavior switch if the transfer call reverts: bubble the revert reason or return a false boolean.
*/
function _safeApprove(IERC20 token, address spender, uint256 value, bool bubble) private returns (bool success) {
bytes4 selector = IERC20.approve.selector;
assembly ("memory-safe") {
let fmp := mload(0x40)
mstore(0x00, selector)
mstore(0x04, and(spender, shr(96, not(0))))
mstore(0x24, value)
success := call(gas(), token, 0, 0x00, 0x44, 0x00, 0x20)
// if call success and return is true, all is good.
// otherwise (not success or return is not true), we need to perform further checks
if iszero(and(success, eq(mload(0x00), 1))) {
// if the call was a failure and bubble is enabled, bubble the error
if and(iszero(success), bubble) {
returndatacopy(fmp, 0x00, returndatasize())
revert(fmp, returndatasize())
}
// if the return value is not true, then the call is only successful if:
// - the token address has code
// - the returndata is empty
success := and(success, and(iszero(returndatasize()), gt(extcodesize(token), 0)))
}
mstore(0x40, fmp)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC1363.sol)
pragma solidity >=0.6.2;
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.4.0) (interfaces/IERC20.sol)
pragma solidity >=0.4.16;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC165.sol)
pragma solidity >=0.4.16;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @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);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"forge-std/=lib/forge-std/src/",
"@morpho-blue/=lib/morpho-blue/src/",
"defisaver-v3-contracts/=lib/defisaver-v3-contracts/",
"ds-test/=lib/morpho-blue/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"morpho-blue/=lib/morpho-blue/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "osaka",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"ReturnIndexValueError","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SubIndexValueError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"logName","type":"string"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ActionEvent","type":"event"},{"inputs":[],"name":"NO_PARAM_MAPPING","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETURN_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MAX_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUB_MIN_INDEX_VALUE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"actionType","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"},{"internalType":"bytes32[]","name":"_subData","type":"bytes32[]"},{"internalType":"uint8[]","name":"_paramMapping","type":"uint8[]"},{"internalType":"bytes32[]","name":"_returnValues","type":"bytes32[]"}],"name":"executeAction","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"executeActionDirect","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"parseInputs","outputs":[{"components":[{"internalType":"address","name":"syToken","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountTokenToDeposit","type":"uint256"},{"internalType":"uint256","name":"minSharesOut","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct PendleSYDeposit.Params","name":"params","type":"tuple"}],"stateMutability":"pure","type":"function"}]Contract Creation Code
6080604052348015600e575f5ffd5b50610cc28061001c5f395ff3fe608060405260043610610084575f3560e01c80638bcb6216116100575780638bcb6216146100ee5780638df50f74146101025780639093410d146101235780639864dcdd1461014f578063d3c2e7ed14610163575f5ffd5b80630f2eee4214610088578063247492f8146100b35780632fa13cb8146100c6578063389f87ff146100d9575b5f5ffd5b348015610093575f5ffd5b5061009c608081565b60405160ff90911681526020015b60405180910390f35b3480156100be575f5ffd5b50600161009c565b3480156100d1575f5ffd5b5061009c5f81565b6100ec6100e73660046108f1565b610177565b005b3480156100f9575f5ffd5b5061009c600181565b6101156101103660046109b0565b61020e565b6040519081526020016100aa565b34801561012e575f5ffd5b5061014261013d3660046108f1565b6102b0565b6040516100aa9190610b09565b34801561015a575f5ffd5b5061009c607f81565b34801561016e575f5ffd5b5061009c60ff81565b5f610181826102b0565b90505f61018d826102f2565b6040516e14195b991b1954d651195c1bdcda5d608a1b8152909150600f0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce383836040516020016101e7929190610b17565b60408051601f198184030181529082905261020191610b32565b60405180910390a2505050565b5f5f61021c868686866103c8565b90505f610228826102f2565b6040516e14195b991b1954d651195c1bdcda5d608a1b8152909150600f0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce38383604051602001610282929190610b17565b60408051601f198184030181529082905261029c91610b32565b60405180910390a29150505b949350505050565b6040805160a0810182525f8082526020808301829052928201819052606082018190526080820152825190916102ec9184018101908401610b7e565b92915050565b8051604082015160208301515f92610315926001600160a01b03909216916104e9565b815160808301516020840151604080860151606087015191516320e8c56560e01b81526001600160a01b0394851660048201529284166024840152604483015260648201525f9291909116906320e8c565906084016020604051808303815f875af1158015610386573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103aa9190610c04565b835160208501519192506102ec916001600160a01b0316905f6104e9565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091526103fb856102b0565b9050610425815f0151845f8151811061041657610416610c1b565b6020026020010151868561052b565b6001600160a01b031681526020810151835161044f91908590600190811061041657610416610c1b565b6001600160a01b031660208201526040810151835161048b91908590600290811061047c5761047c610c1b565b602002602001015186856105d2565b8160400181815250506104af81606001518460038151811061047c5761047c610c1b565b8160600181815250506104d381608001518460048151811061041657610416610c1b565b6001600160a01b03166080820152949350505050565b6001600160a01b0383166104fc57505050565b826105116001600160a01b038216845f610618565b6105256001600160a01b0382168484610618565b50505050565b5f60ff8416156105c95761053e8461069c565b15610572578161054d856106ba565b60ff168151811061056057610560610c1b565b602002602001015160601c94506105c9565b8360ff1660fe036105845750306102a8565b8360ff1660ff0361059f57610598306106ec565b90506102a8565b826105a9856107ad565b60ff16815181106105bc576105bc610c1b565b60200260200101515f1c94505b50929392505050565b5f60ff8416156105c9576105e58461069c565b1561059f57816105f4856106ba565b60ff168151811061060757610607610c1b565b60200260200101515f1c94506105c9565b6106248383835f6107de565b6106975761063583835f60016107de565b61066257604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b61066f83838360016107de565b61069757604051635274afe760e01b81526001600160a01b0384166004820152602401610659565b505050565b5f600160ff8316108015906102ec5750607f60ff8316111592915050565b5f6106c48261069c565b6106e15760405163dcc95a3960e01b815260040160405180910390fd5b6102ec600183610c2f565b60408051600481526024810182526020810180516001600160e01b0316638da5cb5b60e01b17905290515f91829182916001600160a01b038616916107319190610c54565b5f60405180830381855afa9150503d805f8114610769576040519150601f19603f3d011682016040523d82523d5f602084013e61076e565b606091505b509150915081801561078257506020815110155b156107a2578080602001905181019061079b9190610c6a565b92506107a6565b8392505b5050919050565b5f608060ff831610156107d35760405163866f6e8760e01b815260040160405180910390fd5b6102ec608083610c2f565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316610834578383151615610828573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561087d5761087d610840565b604052919050565b5f82601f830112610894575f5ffd5b813567ffffffffffffffff8111156108ae576108ae610840565b6108c1601f8201601f1916602001610854565b8181528460208386010111156108d5575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610901575f5ffd5b813567ffffffffffffffff811115610917575f5ffd5b6102a884828501610885565b5f67ffffffffffffffff82111561093c5761093c610840565b5060051b60200190565b5f82601f830112610955575f5ffd5b813561096861096382610923565b610854565b8082825260208201915060208360051b860101925085831115610989575f5ffd5b602085015b838110156109a657803583526020928301920161098e565b5095945050505050565b5f5f5f5f608085870312156109c3575f5ffd5b843567ffffffffffffffff8111156109d9575f5ffd5b6109e587828801610885565b945050602085013567ffffffffffffffff811115610a01575f5ffd5b610a0d87828801610946565b935050604085013567ffffffffffffffff811115610a29575f5ffd5b8501601f81018713610a39575f5ffd5b8035610a4761096382610923565b8082825260208201915060208360051b850101925089831115610a68575f5ffd5b6020840193505b82841015610a9857833560ff81168114610a87575f5ffd5b825260209384019390910190610a6f565b9450505050606085013567ffffffffffffffff811115610ab6575f5ffd5b610ac287828801610946565b91505092959194509250565b80516001600160a01b039081168352602080830151821690840152604080830151908401526060808301519084015260809182015116910152565b60a081016102ec8284610ace565b60c08101610b258285610ace565b8260a08301529392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114610b7b575f5ffd5b50565b5f60a0828403128015610b8f575f5ffd5b5060405160a0810167ffffffffffffffff81118282101715610bb357610bb3610840565b6040528251610bc181610b67565b81526020830151610bd181610b67565b602082015260408381015190820152606080840151908201526080830151610bf881610b67565b60808201529392505050565b5f60208284031215610c14575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b60ff82811682821603908111156102ec57634e487b7160e01b5f52601160045260245ffd5b5f82518060208501845e5f920191825250919050565b5f60208284031215610c7a575f5ffd5b8151610c8581610b67565b939250505056fea2646970667358221220d1eb9a365cbad49e38ff1582b2c3b368c76155355ef3b0d007280a5029e8970864736f6c634300081d0033
Deployed Bytecode
0x608060405260043610610084575f3560e01c80638bcb6216116100575780638bcb6216146100ee5780638df50f74146101025780639093410d146101235780639864dcdd1461014f578063d3c2e7ed14610163575f5ffd5b80630f2eee4214610088578063247492f8146100b35780632fa13cb8146100c6578063389f87ff146100d9575b5f5ffd5b348015610093575f5ffd5b5061009c608081565b60405160ff90911681526020015b60405180910390f35b3480156100be575f5ffd5b50600161009c565b3480156100d1575f5ffd5b5061009c5f81565b6100ec6100e73660046108f1565b610177565b005b3480156100f9575f5ffd5b5061009c600181565b6101156101103660046109b0565b61020e565b6040519081526020016100aa565b34801561012e575f5ffd5b5061014261013d3660046108f1565b6102b0565b6040516100aa9190610b09565b34801561015a575f5ffd5b5061009c607f81565b34801561016e575f5ffd5b5061009c60ff81565b5f610181826102b0565b90505f61018d826102f2565b6040516e14195b991b1954d651195c1bdcda5d608a1b8152909150600f0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce383836040516020016101e7929190610b17565b60408051601f198184030181529082905261020191610b32565b60405180910390a2505050565b5f5f61021c868686866103c8565b90505f610228826102f2565b6040516e14195b991b1954d651195c1bdcda5d608a1b8152909150600f0160405180910390207f2b6d22f419271bcc89bbac8deec947c664365d6e24d06fef0ca7c325c704dce38383604051602001610282929190610b17565b60408051601f198184030181529082905261029c91610b32565b60405180910390a29150505b949350505050565b6040805160a0810182525f8082526020808301829052928201819052606082018190526080820152825190916102ec9184018101908401610b7e565b92915050565b8051604082015160208301515f92610315926001600160a01b03909216916104e9565b815160808301516020840151604080860151606087015191516320e8c56560e01b81526001600160a01b0394851660048201529284166024840152604483015260648201525f9291909116906320e8c565906084016020604051808303815f875af1158015610386573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103aa9190610c04565b835160208501519192506102ec916001600160a01b0316905f6104e9565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091526103fb856102b0565b9050610425815f0151845f8151811061041657610416610c1b565b6020026020010151868561052b565b6001600160a01b031681526020810151835161044f91908590600190811061041657610416610c1b565b6001600160a01b031660208201526040810151835161048b91908590600290811061047c5761047c610c1b565b602002602001015186856105d2565b8160400181815250506104af81606001518460038151811061047c5761047c610c1b565b8160600181815250506104d381608001518460048151811061041657610416610c1b565b6001600160a01b03166080820152949350505050565b6001600160a01b0383166104fc57505050565b826105116001600160a01b038216845f610618565b6105256001600160a01b0382168484610618565b50505050565b5f60ff8416156105c95761053e8461069c565b15610572578161054d856106ba565b60ff168151811061056057610560610c1b565b602002602001015160601c94506105c9565b8360ff1660fe036105845750306102a8565b8360ff1660ff0361059f57610598306106ec565b90506102a8565b826105a9856107ad565b60ff16815181106105bc576105bc610c1b565b60200260200101515f1c94505b50929392505050565b5f60ff8416156105c9576105e58461069c565b1561059f57816105f4856106ba565b60ff168151811061060757610607610c1b565b60200260200101515f1c94506105c9565b6106248383835f6107de565b6106975761063583835f60016107de565b61066257604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b61066f83838360016107de565b61069757604051635274afe760e01b81526001600160a01b0384166004820152602401610659565b505050565b5f600160ff8316108015906102ec5750607f60ff8316111592915050565b5f6106c48261069c565b6106e15760405163dcc95a3960e01b815260040160405180910390fd5b6102ec600183610c2f565b60408051600481526024810182526020810180516001600160e01b0316638da5cb5b60e01b17905290515f91829182916001600160a01b038616916107319190610c54565b5f60405180830381855afa9150503d805f8114610769576040519150601f19603f3d011682016040523d82523d5f602084013e61076e565b606091505b509150915081801561078257506020815110155b156107a2578080602001905181019061079b9190610c6a565b92506107a6565b8392505b5050919050565b5f608060ff831610156107d35760405163866f6e8760e01b815260040160405180910390fd5b6102ec608083610c2f565b60405163095ea7b360e01b5f8181526001600160a01b038616600452602485905291602083604481808b5af1925060015f51148316610834578383151615610828573d5f823e3d81fd5b5f873b113d1516831692505b60405250949350505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561087d5761087d610840565b604052919050565b5f82601f830112610894575f5ffd5b813567ffffffffffffffff8111156108ae576108ae610840565b6108c1601f8201601f1916602001610854565b8181528460208386010111156108d5575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610901575f5ffd5b813567ffffffffffffffff811115610917575f5ffd5b6102a884828501610885565b5f67ffffffffffffffff82111561093c5761093c610840565b5060051b60200190565b5f82601f830112610955575f5ffd5b813561096861096382610923565b610854565b8082825260208201915060208360051b860101925085831115610989575f5ffd5b602085015b838110156109a657803583526020928301920161098e565b5095945050505050565b5f5f5f5f608085870312156109c3575f5ffd5b843567ffffffffffffffff8111156109d9575f5ffd5b6109e587828801610885565b945050602085013567ffffffffffffffff811115610a01575f5ffd5b610a0d87828801610946565b935050604085013567ffffffffffffffff811115610a29575f5ffd5b8501601f81018713610a39575f5ffd5b8035610a4761096382610923565b8082825260208201915060208360051b850101925089831115610a68575f5ffd5b6020840193505b82841015610a9857833560ff81168114610a87575f5ffd5b825260209384019390910190610a6f565b9450505050606085013567ffffffffffffffff811115610ab6575f5ffd5b610ac287828801610946565b91505092959194509250565b80516001600160a01b039081168352602080830151821690840152604080830151908401526060808301519084015260809182015116910152565b60a081016102ec8284610ace565b60c08101610b258285610ace565b8260a08301529392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114610b7b575f5ffd5b50565b5f60a0828403128015610b8f575f5ffd5b5060405160a0810167ffffffffffffffff81118282101715610bb357610bb3610840565b6040528251610bc181610b67565b81526020830151610bd181610b67565b602082015260408381015190820152606080840151908201526080830151610bf881610b67565b60808201529392505050565b5f60208284031215610c14575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b60ff82811682821603908111156102ec57634e487b7160e01b5f52601160045260245ffd5b5f82518060208501845e5f920191825250919050565b5f60208284031215610c7a575f5ffd5b8151610c8581610b67565b939250505056fea2646970667358221220d1eb9a365cbad49e38ff1582b2c3b368c76155355ef3b0d007280a5029e8970864736f6c634300081d0033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.