PageSourceSearch

https://pwndao-dev-docs.pages.dev/assets/js/3f3d4b54.dd3ed9c8.js

js pwndao-dev-docs.pages.dev collected 2026-10-03 05:31:32 UTC 32,011 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkpwndao_docs=self.webpackChunkpwndao_docs||[]).push([[4012],{5404:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>d});var i=t(6672);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:n},e.children)}},8674:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"smart-contracts/pwn-dao/tokens/vepwn/stake","title":"Stake","description":"1. Summary","source":"@site/docs/smart-contracts/pwn-dao/tokens/vepwn/stake.md","sourceDirName":"smart-contracts/pwn-dao/tokens/vepwn","slug":"/smart-contracts/pwn-dao/tokens/vepwn/stake","permalink":"/smart-contracts/pwn-dao/tokens/vepwn/stake","draft":false,"unlisted":false,"editUrl":"https://github.com/pwndao/pwndao-docs/tree/main/docs/docs/smart-contracts/pwn-dao/tokens/vepwn/stake.md","tags":[],"version":"current","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"vePWN","permalink":"/smart-contracts/pwn-dao/tokens/vepwn/"},"next":{"title":"Power","permalink":"/smart-contracts/pwn-dao/tokens/vepwn/power"}}');var s=t(3420),r=t(5404);const a={},d="Stake",c={},o=[{value:"1. Summary",id:"1-summary",level:2},{value:"2. Important links",id:"2-important-links",level:2},{value:"3. Contract details",id:"3-contract-details",level:2},{value:"Features",id:"features",level:3},{value:"Inherited contracts, implemented Interfaces and ERCs",id:"inherited-contracts-implemented-interfaces-and-ercs",level:3},{value:"Functions",id:"functions",level:3},{value:"Overview",id:"overview",level:4},{value:"Implementation",id:"implementation",level:4},{value:"Overview",id:"overview-1",level:4},{value:"Implementation",id:"implementation-1",level:4},{value:"Overview",id:"overview-2",level:4},{value:"Implementation",id:"implementation-2",level:4},{value:"Overview",id:"overview-3",level:4},{value:"Implementation",id:"implementation-3",level:4},{value:"Overview",id:"overview-4",level:4},{value:"Implementation",id:"implementation-4",level:4},{value:"Overview",id:"overview-5",level:4},{value:"Implementation",id:"implementation-5",level:4},{value:"Overview",id:"overview-6",level:4},{value:"Implementation",id:"implementation-6",level:4},{value:"Overview",id:"overview-7",level:4},{value:"Implementation",id:"implementation-7",level:4},{value:"Overview",id:"overview-8",level:4},{value:"Implementation",id:"implementation-8",level:4},{value:"Events",id:"events",level:3},{value:"<code>StakeData</code> Struct",id:"stakedata-struct",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"stake",children:"Stake"})}),"\n",(0,s.jsx)(n.h2,{id:"1-summary",children:"1. Summary"}),"\n",(0,s.jsx)(n.p,{children:"The vePWN Stake contract is an abstract contract inherited by vePWN. It implements functions to manage stake in PWN DAO. "}),"\n",(0,s.jsx)(n.h2,{id:"2-important-links",children:"2. Important links"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/PWNDAO/pwn_dao/blob/main/src/token/vePWN/VoteEscrowedPWNStake.sol",children:(0,s.jsx)(n.strong,{children:"View on GitHub"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"3-contract-details",children:"3. Contract details"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.em,{children:"VoteEscrowedPWNStake.sol"})," is written in Solidity version 0.8.25"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"features",children:"Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Create, Split, Merge, Increase, Withdraw and Delegate stake"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"inherited-contracts-implemented-interfaces-and-ercs",children:"Inherited contracts, implemented Interfaces and ERCs"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/PWNDAO/pwn_dao/blob/main/src/token/vePWN/VoteEscrowedPWNBase.sol",children:"VoteEscrowedPWNBase"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"functions",children:"Functions"}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"createStake"})}),(0,s.jsx)(n.h4,{id:"overview",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to create a stake."}),(0,s.jsx)(n.p,{children:"This function takes two arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"lockUpEpochs"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function createStake(uint256 amount, uint256 lockUpEpochs) external returns (uint256) {\
1n    return createStakeOnBehalfOf(msg.sender, msg.sender, amount, lockUpEpochs);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"createStakeOnBehalfOf"})}),(0,s.jsx)(n.h4,{id:"overview-1",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to create a stake of behalf of another account."}),(0,s.jsx)(n.p,{children:"This function takes four arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"beneficiary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"lockUpEpochs"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-1",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function createStakeOnBehalfOf(address staker, address beneficiary, uint256 amount, uint256 lockUpEpochs)\n    public\n    returns (uint256 stakeId)\n{\n    // max stake of total initial supply (100M) with decimals 1e26 < max uint88 (3e26)\n    if (amount < 100 || amount > type(uint88).max) {\n        revert Error.InvalidAmount();\n    }\n    // amount must be a multiple of 100 to prevent rounding errors when computing power\n    if (amount % 100 > 0) {\n        revert Error.InvalidAmount();\n    }\n    // lock up for <1; 5> + {10} years\n    if (lockUpEpochs < EPOCHS_IN_YEAR) {\n        revert Error.InvalidLockUpPeriod();\n    }\n    if (lockUpEpochs > 5 * EPOCHS_IN_YEAR && lockUpEpochs != 10 * EPOCHS_IN_YEAR) {\n        revert Error.InvalidLockUpPeriod();\n    }\n\n    uint16 initialEpoch = epochClock.currentEpoch() + 1;\n\n    // store power changes\n    _updateTotalPower(uint104(amount), initialEpoch, uint8(lockUpEpochs), true);\n\n    // create new stake\n    stakeId = _createStake({\n        owner: staker,\n        beneficiary: beneficiary,\n        initialEpoch: initialEpoch,\n        amount: uint104(amount),\n        lockUpEpochs: uint8(lockUpEpochs)\n    });\n\n    // transfer pwn token\n    pwnToken.transferFrom(msg.sender, address(this), amount);\n\n    // emit event\n    emit StakeCreated(stakeId, staker, beneficiary, amount, lockUpEpochs);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"splitStake"})}),(0,s.jsx)(n.h4,{id:"overview-2",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to split a stake into two. Burns the original stPWN NFT and mints two new ones. The beneficiary of the new stake is also the stake owner."}),(0,s.jsx)(n.p,{children:"This function takes three arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeBeneficiary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"splitAmount"})})," - amount of PWN tokens to split into the first new stake"]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-2",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function splitStake(uint256 stakeId, address stakeBeneficiary, uint256 splitAmount)\n    external\n    returns (uint256 newStakeId1, uint256 newStakeId2)\n{\n    address staker = msg.sender;\n    Stake storage originalStake = _stakes[stakeId];\n    uint16 originalInitialEpoch = originalStake.initialEpoch;\n    uint104 originalAmount = originalStake.amount;\n    uint8 originalLockUpEpochs = originalStake.lockUpEpochs;\n\n    // split amount must be greater than 0\n    if (splitAmount == 0) {\n        revert Error.InvalidAmount();\n    }\n    // split amount must be less than stake amount\n    if (splitAmount >= originalAmount) {\n        revert Error.InvalidAmount();\n    }
1\n    // split amount must be a multiple of 100 to prevent rounding errors when computing power\n    if (splitAmount % 100 > 0) {\n        revert Error.InvalidAmount();\n    }\n\n    // delete original stake\n    _deleteStake({ owner: staker, beneficiary: stakeBeneficiary, stakeId: stakeId });\n\n    // create new stakes\n    newStakeId1 = _createStake({\n        owner: staker,\n        beneficiary: staker,\n        initialEpoch: originalInitialEpoch,\n        amount: originalAmount - uint104(splitAmount),\n        lockUpEpochs: originalLockUpEpochs\n    });\n    newStakeId2 = _createStake({\n        owner: staker,\n        beneficiary: staker,\n        initialEpoch: originalInitialEpoch,\n        amount: uint104(splitAmount),\n        lockUpEpochs: originalLockUpEpochs\n    });\n\n    // emit event\n    emit StakeSplit(stakeId, staker, originalAmount - uint104(splitAmount), splitAmount, newStakeId1, newStakeId2);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"mergeStakes"})}),(0,s.jsx)(n.h4,{id:"overview-3",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to merge two stakes into one. Burns both stPWN NFTs and mints a new one. The new stake has lockup period of the first stake with a condition that the first stake lockup must be longer than or equal to the second one. The beneficiary of the new stake is also the stake owner."}),(0,s.jsx)(n.p,{children:"This function takes four arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId1"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeBeneficiary1"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId2"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeBeneficiary2"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-3",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function mergeStakes(uint256 stakeId1, address stakeBeneficiary1, uint256 stakeId2, address stakeBeneficiary2)\n    external\n    returns (uint256 newStakeId)\n{\n    address staker = msg.sender;\n    Stake storage stake1 = _stakes[stakeId1];\n    Stake storage stake2 = _stakes[stakeId2];\n    uint16 finalEpoch1 = stake1.initialEpoch + stake1.lockUpEpochs;\n    uint16 finalEpoch2 = stake2.initialEpoch + stake2.lockUpEpochs;\n    uint16 newInitialEpoch = epochClock.currentEpoch() + 1;\n\n    // the first stake lockup end must be greater than or equal to the second stake lockup end\n    // both stake lockup ends must be greater than the current epoch\n    if (finalEpoch1 < finalEpoch2 || finalEpoch1 <= newInitialEpoch) {\n        revert Error.LockUpPeriodMismatch();\n    }\n\n    uint8 newLockUpEpochs = uint8(finalEpoch1 - newInitialEpoch); // safe cast\n    // only need to update second stake power changes if has different final epoch\n    if (finalEpoch1 != finalEpoch2) {\n        uint104 amount2 = stake2.amount;\n        // clear second stake power changes if necessary\n        if (finalEpoch2 > newInitialEpoch) {\n            _updateTotalPower(amount2, newInitialEpoch, uint8(finalEpoch2 - newInitialEpoch), false);\n        }\n        // store new update power changes\n        _updateTotalPower(amount2, newInitialEpoch, newLockUpEpochs, true);\n    }\n\n    // delete old stakes\n    _deleteStake({ owner: staker, beneficiary: stakeBeneficiary1, stakeId: stakeId1 });\n    _deleteStake({ owner: staker, beneficiary: stakeBeneficiary2, stakeId: stakeId2 });\n\n    // create new stake\n    uint104 newAmount = stake1.amount + stake2.amount;\n    newStakeId = _createStake({\n        owner: staker,\n        beneficiary: staker,\n        initialEpoch: newInitialEpoch,\n        amount: newAmount,\n        lockUpEpochs: newLockUpEpochs\n    });\n\n    // emit event\n    emit StakeMerged(stakeId1, stakeId2, staker, newAmount, newLockUpEpochs, newStakeId);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"increaseStake"})}),(0,s.jsx)(n.h4,{id:"overview-4",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to increase a stake. Both the amount of tokens and the lockup period of a stake can be increased. Old stake NFT is burned and a new one is created during the increase of a stake."}),(0,s.jsx)(n.p,{children:"This function takes four arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeBeneficiary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"additionalAmount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"additionalEpochs"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-4",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function increaseStake(uint256 stakeId, address stakeBeneficiary, uint256 additionalAmount, uint256 additionalEpochs)\n    external\n    returns (uint256 newStakeId)\n{\n    address staker = msg.sender;\n    Stake storage stake = _stakes[stakeId];\n\n    // additional amount or additional epochs must be greater than 0\n    if (additionalAmount == 0 && additionalEpochs == 0) {\n        revert Error.NothingToIncrease();\n    }\n    if (additionalAmount > type(uint88).max) {\n        revert Error.InvalidAmount();\n    }
1\n    // to prevent rounding errors when computing power\n    if (additionalAmount % 100 > 0) {\n        revert Error.InvalidAmount();\n    }\n    if (additionalEpochs > 10 * EPOCHS_IN_YEAR) {\n        revert Error.InvalidLockUpPeriod();\n    }\n\n    uint16 newInitialEpoch = epochClock.currentEpoch() + 1;\n    uint16 oldFinalEpoch = stake.initialEpoch + stake.lockUpEpochs;\n    uint8 newLockUpEpochs = SafeCast.toUint8(\n        oldFinalEpoch <= newInitialEpoch ? additionalEpochs : oldFinalEpoch + additionalEpochs - newInitialEpoch\n    );\n    // extended lockup must be in <1; 5> + {10} years\n    if (newLockUpEpochs < EPOCHS_IN_YEAR) {\n        revert Error.InvalidLockUpPeriod();\n    }\n    if (newLockUpEpochs > 5 * EPOCHS_IN_YEAR && newLockUpEpochs != 10 * EPOCHS_IN_YEAR) {\n        revert Error.InvalidLockUpPeriod();\n    }\n\n    uint104 oldAmount = stake.amount;\n    uint104 newAmount = oldAmount + uint104(additionalAmount); // safe cast\n\n    { // avoid stack too deep\n        bool amountAdditionOnly = additionalEpochs == 0;\n\n        // clear old power changes if adding epochs\n        if (!amountAdditionOnly && newLockUpEpochs > additionalEpochs) {\n            _updateTotalPower(oldAmount, newInitialEpoch, newLockUpEpochs - uint8(additionalEpochs), false);\n        }\n\n        // store new power changes\n        uint104 amount = amountAdditionOnly ? uint104(additionalAmount) : newAmount;\n        _updateTotalPower(amount, newInitialEpoch, newLockUpEpochs, true);\n    }\n\n    // delete original stake\n    _deleteStake({ owner: staker, beneficiary: stakeBeneficiary, stakeId: stakeId });\n\n    // create new stake\n    newStakeId = _createStake({\n        owner: staker,\n        beneficiary: staker,\n        initialEpoch: newInitialEpoch,\n        amount: newAmount,\n        lockUpEpochs: newLockUpEpochs\n    });\n\n    // transfer additional PWN tokens\n    if (additionalAmount > 0) {\n        pwnToken.transferFrom(staker, address(this), additionalAmount);\n    }\n\n    // emit event\n    emit StakeIncreased(\n        stakeId, staker, additionalAmount, newAmount, additionalEpochs, newLockUpEpochs, newStakeId\n    );\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"withdrawStake"})}),(0,s.jsx)(n.h4,{id:"overview-5",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to withdraw a stake. Burns the stake NFT and transfers the underlying PWN tokens to the caller."}),(0,s.jsx)(n.p,{children:"This function takes two arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeBeneficiary"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-5",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function withdrawStake(uint256 stakeId, address stakeBeneficiary) external {\n    address staker = msg.sender;\n    Stake storage stake = _stakes[stakeId];\n\n    // stake must be unlocked\n    if (stake.initialEpoch + stake.lockUpEpochs > epochClock.currentEpoch()) {\n        revert Error.WithrawalBeforeLockUpEnd();\n    }\n\n    // delete stake\n    _deleteStake({ owner: staker, beneficiary: stakeBeneficiary, stakeId: stakeId });\n\n    // transfer pwn tokens to the staker\n    pwnToken.transfer(staker, stake.amount);\n\n    // emit event\n    emit StakeWithdrawn(stakeId, staker, stake.amount);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"delegateStakePower"})}),(0,s.jsx)(n.h4,{id:"overview-6",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to delegate stakes voting power to another account."}),(0,s.jsx)(n.p,{children:"This function takes three arguments:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"currentBeneficiary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newBeneficiary"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-6",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function delegateStakePower(uint256 stakeId, address currentBeneficiary, address newBeneficiary) external {\n    address staker = msg.sender;\n\n    // power already delegated to the new beneficiary\n    if (currentBeneficiary == newBeneficiary) {\n        revert Error.SameBeneficiary();\n    }\n\n    // staker must be stake owner\n    _checkIsStakeOwner(staker, stakeId);
1\n\n    // remove token from current beneficiary first to avoid duplicates\n    _removeStakeFromBeneficiary(stakeId, currentBeneficiary);\n    _addStakeToBeneficiary(stakeId, newBeneficiary);\n\n    // emit event\n    emit StakePowerDelegated(stakeId, currentBeneficiary, newBeneficiary);\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"getStake"})}),(0,s.jsx)(n.h4,{id:"overview-7",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to get information about a stake."}),(0,s.jsxs)(n.p,{children:["Checkout ",(0,s.jsx)(n.a,{href:"/smart-contracts/pwn-dao/tokens/vepwn/stake#stakedata-struct",children:(0,s.jsx)(n.code,{children:"StakeData"})})," struct definition below to learn more about the return type of this function."]}),(0,s.jsx)(n.p,{children:"This function takes one argument:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-7",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function getStake(uint256 stakeId) public view returns (StakeData memory stakeData) {\n    Stake storage stake = _stakes[stakeId];\n    uint16 currentEpoch = epochClock.currentEpoch();\n\n    stakeData.stakeId = stakeId;\n    stakeData.owner = stakedPWN.ownerOf(stakeId);\n    stakeData.initialEpoch = stake.initialEpoch;\n    stakeData.lockUpEpochs = stake.lockUpEpochs;\n    stakeData.remainingEpochs = (stakeData.initialEpoch + stakeData.lockUpEpochs >= currentEpoch)\n        ? uint8(stakeData.initialEpoch + stakeData.lockUpEpochs - currentEpoch) : 0;\n    stakeData.currentMultiplier = (stakeData.initialEpoch <= currentEpoch && stakeData.remainingEpochs > 0)\n        ? uint8(uint104(_power(100, stakeData.remainingEpochs))) : 0;\n    stakeData.amount = stake.amount;\n}\n"})})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"getStakes"})}),(0,s.jsx)(n.h4,{id:"overview-8",children:"Overview"}),(0,s.jsx)(n.p,{children:"Function to get information about multiple stakes."}),(0,s.jsxs)(n.p,{children:["Checkout ",(0,s.jsx)(n.a,{href:"/smart-contracts/pwn-dao/tokens/vepwn/stake#stakedata-struct",children:(0,s.jsx)(n.code,{children:"StakeData"})})," struct definition below to learn more about the return type of this function."]}),(0,s.jsx)(n.p,{children:"This function takes one argument:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256[] calldata"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeIds"})})]}),"\n"]}),(0,s.jsx)(n.h4,{id:"implementation-8",children:"Implementation"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"function getStakes(uint256[] calldata stakeIds) external view returns (StakeData[] memory stakeData) {\n    stakeData = new StakeData[](stakeIds.length);\n    for (uint256 i; i < stakeIds.length; ++i) {\n        stakeData[i] = getStake(stakeIds[i]);\n    }\n}\n"})})]}),"\n",(0,s.jsx)(n.h3,{id:"events",children:"Events"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"event StakeCreated(uint256 indexed stakeId, address indexed staker, address indexed beneficiary, uint256 amount, uint256 lockUpEpochs);\nevent StakeSplit(uint256 indexed stakeId, address indexed staker, uint256 amount1, uint256 amount2, uint256 newStakeId1, uint256 newStakeId2);\nevent StakeMerged(uint256 indexed stakeId1, uint256 indexed stakeId2, address indexed staker, uint256 amount, uint256 lockUpEpochs, uint256 newStakeId);\nevent StakeIncreased(uint256 indexed stakeId, address indexed staker, uint256 additionalAmount, uint256 newAmount, uint256 additionalEpochs, uint256 newEpochs, uint256 newStakeId);\nevent StakeWithdrawn(uint256 indexed stakeId, address indexed staker, uint256 amount);\nevent StakePowerDelegated(uint256 indexed stakeId, address indexed originalBeneficiary, address indexed newBeneficiary);\n"})}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakeCreated"})}),(0,s.jsx)(n.p,{children:"StakeCreated event is emitted when a stake is created."}),(0,s.jsx)(n.p,{children:"This event has five parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"benef
1iciary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"lockUpEpochs"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakeSplit"})}),(0,s.jsx)(n.p,{children:"StakeSplit event is emitted when a stake is split into two."}),(0,s.jsx)(n.p,{children:"This event has six parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount1"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount2"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newStakeId1"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newStakeId2"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakeMerged"})}),(0,s.jsx)(n.p,{children:"StakeMerged event is emitted when two stakes are merged into one."}),(0,s.jsx)(n.p,{children:"This event has six parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId1"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId2"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"lockUpEpochs"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newStakeId"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakeIncreased"})}),(0,s.jsx)(n.p,{children:"StakeIncreased event is emitted when a stake is increased. Both the amount of tokens and the lockup period can be increased. Old stake NFT is burned and a new one is created during the increase of a stake."}),(0,s.jsx)(n.p,{children:"This event has seven parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"additionalAmount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newAmount"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"additionalEpochs"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newEpochs"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newStakeId"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakeWithdrawn"})}),(0,s.jsx)(n.p,{children:"StakeWithdrawn event is emitted when a stake is withdrawn."}),(0,s.jsx)(n.p,{children:"This event has three parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"staker"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"amount"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(t,{children:[(0,s.jsx)("summary",{children:(0,s.jsx)("code",{children:"StakePowerDelegated"})}),(0,s.jsxs)(n.p,{children:["StakePowerDelegated event is emitted when stake power is transferred between beneficiaries. When a stake is created, the ",(0,s.jsx)(n.code,{children:"originalBeneficiary"})," is zero address. When a stake is deleted, the ",(0,s.jsx)(n.code,{children:"newBeneficiary"})," is zero address."]}),(0,s.jsx)(n.p,{children:"This event has three parameters:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"uint256 indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"stakeId"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"originalBeneficiary"})})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"address indexed"}),(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"newBeneficiary"})})]}),"\n"]})]}),"\n",(0,s.jsxs)(n.h3,{id:"stakedata-struct",children:[(0,s.jsx)(n.code,{children:"StakeData"})," Struct"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-solidity",children:"struct StakeData {\n    uint256 stakeId;\n    address owner;\n    uint16 initialEpoch;\n    uint8 lockUpEpochs;\n    uint8 remainingEpochs;\n    uint8 currentMultiplier;\n    uint104 amount;
1\n}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.