Module 7 - Understanding Stader Adapter Contract
Here’s the Stader Adapter Contract -
// SPDX-License-Identifier: MITpragma solidity ^0.8.18;
import {IStaderPool} from "./Interfaces.sol";import {RouterIntentEoaAdapterWithoutDataProvider, EoaExecutorWithoutDataProvider} from "@routerprotocol/intents-core/contracts/RouterIntentEoaAdapter.sol";import {Errors} from "@routerprotocol/intents-core/contracts/utils/Errors.sol";import {IERC20, SafeERC20} from "../../../utils/SafeERC20.sol";
/** * @title StaderStakeEth * @author Shivam Agrawal * @notice Staking ETH to receive EthX on Stader. * @notice This contract is only for Ethereum chain. */contract StaderStakeEth is RouterIntentEoaAdapterWithoutDataProvider { using SafeERC20 for IERC20;
address public immutable ethx; IStaderPool public immutable staderPool;
constructor( address __native, address __wnative, address __ethx, address __staderPool ) RouterIntentEoaAdapterWithoutDataProvider(__native, __wnative) { ethx = __ethx; staderPool = IStaderPool(__staderPool); }
function name() public pure override returns (string memory) { return "StaderStakeEth"; }
/** * @inheritdoc EoaExecutorWithoutDataProvider */ function execute( bytes calldata data ) external payable override returns (address[] memory tokens) { (address _recipient, uint256 _amount) = parseInputs(data);
// If the adapter is called using `call` and not `delegatecall` if (address(this) == self()) { require( msg.value == _amount, Errors.INSUFFICIENT_NATIVE_FUNDS_PASSED ); } else if (_amount == type(uint256).max) _amount = address(this).balance;
bytes memory logData;
(tokens, logData) = _stake(_recipient, _amount);
emit ExecutionEvent(name(), logData); return tokens; }
//////////////////////////// ACTION LOGIC ////////////////////////////
function _stake( address _recipient, uint256 _amount ) internal returns (address[] memory tokens, bytes memory logData) { staderPool.deposit{value: _amount}(_recipient);
tokens = new address[](2); tokens[0] = native(); tokens[1] = ethx;
logData = abi.encode(_recipient, _amount); }
/** * @dev function to parse input data. * @param data input data. */ function parseInputs( bytes memory data ) public pure returns (address, uint256) { return abi.decode(data, (address, uint256)); }
// solhint-disable-next-line no-empty-blocks receive() external payable {}}
The StaderStakeEth
Contract allows users to Stake ETH on the Stader Protocol to Receive EthX in return. It is Designed Specifically for the Ethereum Chain and extends the RouterIntentEoaAdapterWithoutDataProvider
to Implement Staking functionality. This Contract Integrates with the Stader Pool to facilitate the Staking Process.
Contract StaderStakeEth.sol
The StaderStakeEth
Contract is an Adapter that enables Users to Stake their ETH on Stader and receive EthX in return. The Contract extends RouterIntentEoaAdapterWithoutDataProvider
and overrides the execute
function to implement the Core Staking Logic.
Inheritance
RouterIntentEoaAdapterWithoutDataProvider
: The Base Contract for EOAs (Externally Owned Accounts) without a Data Provider.EoaExecutorWithoutDataProvider
: Provides theexecute
function, which is overridden in this Contract.
Constructor
The Constructor Initializes the Contract with essential Addresses, including the Native Token, Wrapped Native Token, EthX Token, and the Stader Pool Address.
constructor( address __native, address __wnative, address __ethx, address __staderPool) RouterIntentEoaAdapterWithoutDataProvider(__native, __wnative) { ethx = __ethx; staderPool = IStaderPool(__staderPool);}
- Parameters -
__native
: Address of the Native Token (e.g., ETH).__wnative
: Address of the Wrapped Native Token (e.g., WETH).__ethx
: Address of the EthX Token on Stader.__staderPool
: Address of the Stader Pool Contract where Staking is Performed.
Functions
- name(): Returns the Name of the Adapter. It returns a String representing the name of the Adapter,
StaderStakeEth
.
function name() public pure override returns (string memory)
- execute(): Executes the Staking Logic by Calling the
execute
function of the Adapter. This function Decodes the Input Data, checks for Sufficient Native Funds, and Performs the Staking Action.
function execute( bytes calldata data) external payable override returns (address[] memory tokens)
-
Parameters -
a)
data
: Encoded Input Data containing the Recipient Address and the amount of ETH to be Staked. -
Returns -
a)
tokens
: An array of Token Addresses involved in the Transaction (Native Token and EthX). -
Functionality -
a) Decodes the Input Data to Retrieve the Recipient Address and Staking Amount.
b) Verifies if the Contract is called using
call
and Checks if the Correct Amount of Native funds is Passed.c) Executes the
_stake
function to Stake ETH on the Stader Pool.
- _stake(): Handles the Core Staking Logic. It Deposits the Specified amount of ETH to the Stader Pool and returns the involved Tokens and Log Data.
function _stake( address _recipient, uint256 _amount) internal returns (address[] memory tokens, bytes memory logData)
-
Parameters -
a)
_recipient
: The Address that will Receive the EthX Tokens. b)_amount
: The Amount of ETH to be Staked. -
Returns -
a)
tokens
: An array of Token Addresses involved in the Transaction (Native Token and EthX). b)logData
: Encoded Log Data containing the Execution Event. -
Functionality -
a) Deposits ETH into the Stader Pool using the provided Recipient Address.
b) Constructs an array of Token Addresses (Native Token and EthX).
c) Encodes Log Data containing the Recipient and Amount.
- parseInputs(): Parses the Input Data to Extract the Recipient Address and the Amount of ETH to be Staked.
function parseInputs( bytes memory data) public pure returns (address, uint256)
-
Parameters -
a)
data
: Encoded Input Data containing the Recipient Address and Staking Amount. -
Returns - A Tuple Containing -
a)
address
: The Recepient Address. b)uint256
: The Amount of ETH to be Staked.
Conclusion
Before Going on to the Next Module Let’s Understand Two More Adapters -
- Nitro Adapter: This is used to Bridge the Assets or Send Message or do Both from One Chain to another.
- Dexspan Adapter: This is used to Swap one Asset to another on the Same Chain.