BlockscapeETHStakeNFT

Git Source

Inherits: ERC1155Supply, ReentrancyGuard, BlockscapeAccess, BlockscapeShared

Author: Blockscape Finance AG info@blockscape.network

collects ETH, mints NFT in return for stake, which can be any amount of ETH. The ETH is staked in the blockscape rocketpool infrastructure.

State Variables

poolSupply

tracks the ETH pool supply

uint256 private poolSupply;

name

constant used for blockexplorers to display the name of the token (as to be lower case as per blockexplorer standards)

string public constant name = "Blockscape ETH Stake NFTs";

symbol

constant used for blockexplorers to display the symbol of the token (as to be lower case as per blockexplorer standards)

string public constant symbol = "BSS";

Functions

constructor

each pool related vault gets its separate tokenID which depicts the nft for each staker

the IPNS makes sure the nfts stay reachable via this link while new nfts get added to the underlying ipfs folder

constructor()
    ERC1155("https://ipfs.blockscape.network/ipns/" "TBD/" "{id}.json")
    BlockscapeAccess(msg.sender, BlockscapeShared.blockscapeRocketPoolNode, msg.sender);

supportsInterface

needed as the OZ ERC1155 && AccessControl does both implement the supportsInterface function

function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, AccessControl) returns (bool);

depositStakeNFT

used by stakers to deposit ETH into the contract

the vault must be open and enough RPL must be staked in the rocketpool by the node

the msg.value must be greater than 0

the msg.value is added to the poolSupply

if contract balance is greater than 8 ETH, the ETH is sent to the rocketpool node

function depositStakeNFT() external payable nonReentrant;

updateStake

update the stake of the given tokenID, if the NFT owner decides to stake more ETH

emits the StakeUpdated event & increases the poolSupply based on the msg.value

function updateStake(uint256 _tokenID) external payable;

Parameters

NameTypeDescription
_tokenIDuint256Identifier of the vault

prepareWithdrawalProcess

Withdraw is a two step process, first the staker has to call prepareWithdrawalProcess()

first step used by the staker when he or she wants to unstake

function prepareWithdrawalProcess(uint256 _tokenID) external override;

Parameters

NameTypeDescription
_tokenIDuint256which ETH Stake NFT the staker wants to unstake the backend will listen on the event and will unstake the validator. The ETH value with rewards is transparantly available via beacon chain explorers and will be reduced by the withdraw fee, which is fixed to 0.5% after one year.

withdrawFunds

used by the staker after prepareWithdrawalProcess() & the timelock has passed to withdraw the funds

the rewards are calculated by the backend controller and are then stored in the contract, this is needed to be able to calculate the rewards correctly including MEV rewards. There off-chain calculated rewards cannot be lower than the on-chain esimated rewards.

function withdrawFunds(uint256 _tokenID) external override nonReentrant;

getPoolSupply

returns the current ETH supply of the pool

function getPoolSupply() public view returns (uint256);

calcWithdrawFee

how much fees would the user have to pay if he or she would to unstake now within the first year of staking the fee is starting at 20% & decreasing linearly, afterwards 0.5%

function calcWithdrawFee(uint256 _tokenID, address _user) public view override returns (uint256 _amount);

Parameters

NameTypeDescription
_tokenIDuint256which NFT the staker wants to unstake
_useraddress

Returns

NameTypeDescription
_amountuint256how much the user would pay on fees in percent*1e18

calcApr

this function is a on-chain calculation of the rocketpool ETH rewards.

It does take MEV (estimated) into account.

exp(((31556926 / 384) * 64) / 31622 / sqrt(balanceStaked)) - 1) * 100 - 0.5

31556926 = seconds per year

384 = seconds per epoch

31556926 / 384 = epochs per year

64 = BASE_REWARD_FACTOR

31622 = sqrt(gwei per ETH)

166.32368815e18 = ((31556926 / 384) * 64) / 31622

0x00000000219ab540356cBB839Cbe05303d7705Fa = deposit contract address

function calcApr() internal view returns (uint256);

Returns

NameTypeDescription
<none>uint256rewards annual procentage rate * 1e18

calcRewards

calculates the rewards for the staker based on the current APR and the time staked

function calcRewards(uint256 _tokenID) internal view returns (uint256);

Parameters

NameTypeDescription
_tokenIDuint256which the rewards are calculated for

Returns

NameTypeDescription
<none>uint256ETH rewards in wei minus the withdraw fee

totalSupply

how many NFTs are there totally

function totalSupply() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256total amount of NFTs minted

contractURI

stake nft metdata location

this path will never change as the contract defines a collection

function contractURI() external pure returns (string memory);

Returns

NameTypeDescription
<none>stringthe fixed collection metadata path

uri

gets the url to the metadata of a given NFT tokenID

function uri(uint256 _tokenID) public pure override returns (string memory);

Parameters

NameTypeDescription
_tokenIDuint256the pool

Returns

NameTypeDescription
<none>stringthe NFT metadata url