{"id":"ny6_YIlkxYM","title":"NEAR Live Contract Review | Episode 2: Staking Pool Contracts","description":"The second episode of our live contracts review series is about Staking Pool Smart Contracts. Get insights and explanations directly from NEAR Core team members as they talk through the intricacies of important contracts on NEAR.\n\nFollow the latest from NEAR:\n\nWebsite: https://nearprotocol.com/\nDiscord: https://near.ai/discord\nMedium: https://near.ai/medium\nTwitter: https://near.ai/twitter\nGitHub: https://near.ai/github\n\n#LiveContractReview #Blockchain #FutureIsNEAR","channel_name":"NEAR Protocol","published_at":"2020-10-29T00:00:00.000Z","thumbnail_url":"https://img.youtube.com/vi/ny6_YIlkxYM/hqdefault.jpg","transcript_text":"hey i'm eugene and i'm here with mike sheriff chad and josh and this is the second episode of live contract reviews and today we're gonna review stake staking pool contract which is used right now to secure near protocol proof of stake system basically all validators that currently are running on your protocol are running on behalf of the contract so they don't control the account themselves that stakes the amount for proof of stake but instead the contract stakes this amount and they just provide a staking pool and they run their nose and today we're gonna dig into this contract and let me present my window all right um so i hope you can see it so in the core contracts we have a stake in pool account or a stake in pool contract and it's a little more complicated than the previous contract that we reviewed the voting contract so today we're going to focus more on the logic and less on the near bench and russ specific stuff but it will probably involve a little more of a near protocol knowledge so as before the contract starts um from the main structure in this case it's a stake in contract structure as you can see there's a nearby gene and burst direct of more serialized serialize and the structure now has way more field than the past and there are some comments on them probably most of them are up to date the logic of the staking pool contract allows to do the following basically anyone can deposit some amount of near tokens to the staking pool and delegate them to the staking pool by staking on the pool that allows to bundle together balances from multiple people we call them accounts here into one large stake and this way this large state may actually qualify for validator sheets and your protocol has a limited amount of seats right now for a single chart there's at most hundred validator seats you can think about the cities if you take the total amount of token staked and divided by 100 the minimum so this number will be a minimum amount required for a single seat something like this except it's a little bit more complicated to involve removing the stakes that are not qualified to do this minimum amount and stuff like this but this contract basically is a contract standalone contract without any exit key on it that is controlled by the owner in this case owner is provided into initialization so let's go to initialization method similar as before it has three arguments and first is owner id owner id is the account id of the owner account and owner has a bunch of permissions on this contract that allowed the contract to um to perform actions that are not available for the rest of the accounts so if their account and one of these methods was to vote vote on behalf of the staking pool to the voting contract that we'll discuss last time so the owner can call world um vote method we verify that the predecessor equals to the owner so this method uh can only be called by the owner so welcome bone to joining our meeting so at this meeting we basically uh go through a contract and we record it and later we publish it so the community can see the logic and understand how the contracts are implemented on near specifically rust contracts so the vote method is first thing it does it verifies that the method was only called by the owner and then it verifies that some logic but that's not important right now so the contract is the owner and this owner can do certain things so it has the extra permissions then it takes a few more fields it's taking stake public key so when you stake on your protocol you need to provide a public key that will be used by your validator node to to sign messages on behalf of the validator node and this public key can be different from any access key and ideally it should be different from any access key because your node may be run in a data center that can be vulnerable to some attacks and in this case the most they can do is actually do something bad to the network but not to your account and they cannot steal your fonts and you can replace this key easily comparing to you need to like replace the bad access key and finally the third argument that the contract takes is initial reward fee for action so this is the commission that the owner of the staking pool takes on on for running the validator node and this is a fraction that has numerator and denominator and it allows you to basically say for example i take one percent of the rewards for running this particular pool and if let's say you have a million tokens they acquired some reward let's say 10 000 tokens in your work then the owner will take one percent out of this which is 100 can i ask tokens quick question yes um so i've heard this in discord before um people wondering about using floats um and maybe can we talk a little bit about why we have a numerator and denominator um for this kind of percentage stuff right so floats which has an unpredictable behavior when you multiply them and you acting on the floats while this piece is can be for fractions for example you can use a math with larger number of bits so the way you for example do division is you first multiply the amount which is u128 by this numerator and this already can overflow u128 but that's why we do this in u256 and then you divide it by the denominator which should bring it below u128 again which gives you higher precision than for example flood 64 that cannot operate with you 128 bits precision so it will have some rounding errors like precision errors when you do the mass so you either need like a higher precision floats which are not really different from the mass we simulate this u256 does this make sense cool yeah thank you also i think solidity originally doesn't support floats and we originally also did not support floats but that cast some issues around string formatting and rust for debugging so we decided that there is no harm in supporting floats especially as we standardize this on the vm side so biggest issue with slot was undefined behavior around like certain values of loads like what means for example when you have infinite flow to what other beats uh contain so we standardize this and now they are equivalent platform independent so it's okay to use plots now in our vm environment so again standard practice this in it is we first check that the state doesn't exist then we verify input up to certain things that we can do so first thing we do we verify that the fraction is valid and we check that denominator is not zero and else numerator is less than equal than denominator which makes a fraction is less than equal to one this is important to avoid some logic mistakes next thing we do is we verify that the account is valid so this contract was written before some of the helper metric exists so now we have for example valid account id in json types that does this check automatically during the decentralization and if it's invalid it will just panic next thing we do we pull the account balance the current account balance of this taking contract so this balance has to is usually large enough because it has to pay for the storage of this particular contract and then we say we gonna allocate some tokens for price guarantee fund so the staking pool has certain guarantees that are important for local contracts and guarantees are when you deposit to the staking pool you should be able to withdraw at least the same amount of tokens and you cannot lose tokens even like one yacht and year on this contract by depositing and withdrawing from the staking pools so this uh stake share price guarantee fund is around and around 1 trillion yocton year which we consume usually around one or two yuctan year for rounding errors and we can get into details of how this works and finally we remember what's the balance that we're gonna stake on behalf of this contract itself this is required to establish some baseline to limit the rounding differences and we verify that the account doesn't stake already so this might break some logic and we don't want this to happen so we want to initialize the contract before it stakes anything finally we initialize the structure but we don't return it immediately we just created the structure here and then we issue a risk-taking transaction this is important because we make sure that this taken key that was provided is a valid rosette restricted eg 250 or 25 something like 5 119 valid key so there are some keys on the curve that are valid keys but not restricted specific and validators keys can only be restrata specific so this is a near protocol specific scene and what happens is it makes a staking transaction this is the given key and once this transaction is created from the contract when it leaves we do validation on this transaction and if the key is invalid then it will throw an error and entire sync initialization of this taken pool will fail so if you pass invalid staking key public key as an input then your contract consolidation and deployment and all this that happens in one batch transaction will be reverted and this is important so the pool doesn't have an invalid key because that might be allowing you to block the stake of other people and we don't wanna so as part of guarantees we're saying if you're on stake your tokens will be returned in four epochs so they will be eligible for withdrawal this is again important for lockups um to be able to return them to lookups i think this is too much details be before i explain the high level of how contract works and how balances works so we should probably go here and explain the concept of how we actually can distribute rewards to account owners in a constant time when an epoch passes so this is important for most of the smart contracts they want to act in a constant time for every method instead of a linear time for the amount of users because if the amount of users grow then the um the amount of gas required to operate a linear scale will grow as well and eventually will run out of gas so that's why all smart contracts have to act in a constant time usually algorithmic so the way it works for every user we keep structure called account so every user that delegated to this speaking pool will have a structure called account that has the following fields and staked is the balance in the octane year that is not staked so it's just a balance of the user then stake shares is actually a balanced but not in near but instead in a number of stake shares so stake share is a concept that was added to this particular staking pool and the way it works is when you state you buy you essentially mean new shares at the current price by converting your on state balance into stake shares so a stake share price originally is one but over time it grows with rewards and when the account receives rewards its uh total stake balance increases but the amount of total stake shares doesn't change so essentially when an account receives validation rewards or some other deposits straight to the balance that increases the amount that you can receive for every state share so the example can be the following let's say you had originally one million year that was deposited to this account let's say you get one million shares ignoring the yorkton year for now now if this token if the staking pool received um 10 000 near in reward you still have 1 million shares but this 1 million shares now corresponds to 1 million and 10 000 year now if someone else wants to stake at this time they will purchase stake shares internally within the contract at the price of um 1.001 that is because every share now is equal to 100 1 year now when you receive another reward you don't need there's the total balance and in the constant time everybody share the reward proportionally to the number of shares they have now when you're on state you're essentially selling these shares or burning them in concept of fungible tokens in favor of unstaked balance so you sell at the current price so you decrease the total amount of stake as well as total amount of shares and when you purchase you increase the total stake balance and the total stake shares while keeping the price at the constant so when you buy or like when you stake on stake you don't change the price when you receive the reward you increase the price so the price can only go up uh so this may lead to the rounding errors when you have when your yoked and your balance cannot correspond precisely and that's why we have this guarantee fund of like 10 trillion or like 1 trillion yak 10 years that will throw one extra yokta a few times and finally the final part is because the near protocol does not unstake and return the balance immediately it has to wait three epochs until your balance will became unstaked and returned to the account so unlocked so if you're on stake you cannot withdraw this balance immediately from the staking pool you need to wait three epochs and do you remember at which epoch height you called the last and stake action and after interior three e-books your balance will became unlocked and you should be able to withdraw from one state but there's one caveat resist if you call and state at the last block of the epoch the actual promise that does unstaking will arrive for the next epoch first block of the next epoch and that will delay your uh locked balance to become unlocked for four epochs instead of three because we recorded the e-book in the previous block but the actual transaction happened in the next block on the next epoch and to make sure that doesn't happen we log the balance by four e-books instead of three e-books to account for this border case so that's an account um does it make sense so far of like how the high-level logic works from stake and stake shares yeah okay so let's uh i've i've got a couple of questions but i don't know if this is the right place for them like in terms of the yeah you decide in terms of the design of this was this pre-designed or for example num stake shares and this kind of you know simplification of having you know internal uh shares that people buy into at different periods sometimes you know people will make a design choice like that to to simplify a bunch of kind of noise you know arithmetic noise or whatever that's spread around the code and you kind of factor it out into this new idea that makes things easier or did you kind of start with this idea i i'd be curious like like when and how some of these decisions were made what the the um the kind of the driver was to make the decision because that might help uh developers recognize those moments in their own code and say oh yeah i kind of run into the same problem maybe i should do this or that right so i think well the idea of shares is not that new because on ethereum majority of like providers liquidity providers and automated market makers use this similar concept so when you for example um deposit to the liquidity pool you get some kind of token from this tool instead of actual amount of um that represented there and when you withdraw from the pool located pool then you burn this token and get the actual represented tokens so the idea is very similar to to call them shares is somewhat because they have a corresponding price so we could have called them differently it was almost from the beginning of this taking pool contract because we needed a way to represent well not really like there was exploration around how we can do this properly and one way was we limit the number of accounts that can deposit to a given pool to account for this particular update and eventually we landed on the constant time and it was actually simpler model constant complexity time and then the mass of this became somewhat reasonable even so there's some complexity as well involved there so let me probably go through this contract it's not as well structured as for example a lock-up contract because lockup isn't even more complicated so the types are still bundled in the same contract so there is a bunch of types of for example revolt fraction is a separate type um account is a separate type and there's also a human readable account there's a type that only used for view calls so it's not used for logic internally then after you finish with all the types we have a cross contract calls using a high level interface so there's two of them the way it works is you have a macro from nearby engine called x contract standing for external contract you can give a short name that it will generate that you will be able to use and then you have a trade description describing the interface of external contract that you want to do and this describes that you can call a meta vote on a remote contract and pass one argument which is is vote true or false bullying now you will be able to create a promise when you need it and pass a positional argument instead of a json serialized argument and the macro behind the synth will make it into low-level promise apis and the second interface for a callback on ourselves so this is fairly comp common you can call it excel so when you need to do a callback and do something on on the result of the asynchronous promise you can have this type of interface and what we do we check if this taken action succeeded and we'll may get to this detail if it's we have time so finally we have this main implementation structure um implementation body of the staking pool so we went through the constructor so the next um method so this contract is split into multiple modules so you have um so this is a liberals which is the main input and now also you have internal module the internal module has the implementation without um nearby macro so none of these methods will be visible to be called by a contract by someone else on the chain they only can be called within this contract internally so they don't generate json formats and don't deserialize state so they all act as a regular rust methods so the way inter again high level how this contract works is when an epoch passes you may acquire certain rewards the as a validator so we have a method ping which pings the contract so method checks if the there's e-podcast and then we need to distribute rewards and we'll go there for the logic later and if ebook change then it will also restate because the there might be some change in the amount of total stake the contract has to take the next is deposit deposit is a payable which means it can accept an attached deposit so this is similar to ethereum um decorator that allows to receive fonts only to the methods that expect them so nearby gen by default will panic if you try to call a method for example pink and attach a deposit to this method and payable allows to attach deposit so every method there's a internal pink to make sure we distributed previous rewards before changing any logic and the common structure is if we need to restake then we first do some logic and then restake so this is next methods depositive stake this combination between two methods of like first you deposit balance to the state balance of your account and also you want to stake the same amount immediately instead of doing two transactions it's also payable because it also accepts a deposit so next is withdraw all withdraw all uh tries to withdraw all entire unstate balance from the account that called it so when you call or when you interact with the staking pool you need to interact with the account that is owns the balance so in this case this is a predecessor account id and the logic is we basically check the account and then we this draw dance take them out if we can and if it's not then it will panic for example if it's still locked due to unstaking for epochs ago lesson for epoxy this draw allows to withdraw the balance that is not not all balanced but only partial balance then stake all is um stakes all unstaked balance and it's pretty rare to have this method because you usually use depositing stake and it already has all the steak balance then steak you just take some amount of steak balance i think moonlight wallet uses separate cost to deposit in steak but they use a batched transaction to do this finally you have one stakehold it's on stakehold it takes your current amount in um so it basically unstakes all your stake shares by converting them to your tenure so this is the helper method which saying convert my shares number of shares to amount to yoktan near amount and round down because we cannot give you extra for your share multiplied by price and that's how we get the amount and then we call and stake for the given amount so this logic is the following it uses u256 because we operate balances operate on u128 and to avoid overflow we do the following we multiply the balance by number of shares so basically this is the price this two divided and rounding down and equivalent is we have a round up but it's reverse and it's uh state amount round it up here's a round up roundup is very similar except we do this check that allows to round up and then we cast it back to you 128. okay so this one stay called then we have a stakeout action which is very similar to unstable except you pass the amount and then there's a bunch of getter methods that view calls that return you some amounts so you can get the state balance state balance total balance check if you can withdraw then you can get total stake balance this is the total amount the staking pool has inactive stake then you can get who is the owner of the staking pool you can get the current reward fee or commission of the staking pool get the current staking key and there's a separate thing that allows the owner to pause the station from let's say the owners does a migration on the staking pool on the node so something they need to completely unstake for example so they can pause the staking pool which will send a state transaction to the near protocol and then will not restake until until they resume the staking pool but you can still withdraw your balances but you will stop acquiring rewards after it's passed finally you can get a human readable account so it gives you instead of giving you number of shares we give you how much tokens you actually have for the number of shares at the current price and finally saying can you withdraw a note then it gives you a number of accounts number of delegators to this taking post and you can also uh retrieve multiple delegators at once so this is a pagination on um on the large number of accounts within the unordered map and the way you do this is one way of doing this is you use the helper that we call keys as a vector from the unaltered map it gives you persistent collection of keys from the map and then you can use iterator to request accounts from these keys so that's not the most efficient way but it is allows you to implement visionation on an ordered maps and finally this is the callback that we will probably skip for now and there is a bunch of owners method so owner method is the method that can only be called by the owner so owner can update the stake input key let's say they have a different node and need to use a different key so all these methods first check that the only owner could call it this is the method that changes the commission on the staking pool so owner can change the commission that will be active at the at this epoch starting from this epoch immediately but all the previous commissions will be calculated using the previous fee then this was a vote that allowed us to transition to phase two of the mainnet and two methods that i described which allowed to pause taking and to resume staking and finally we have tests here so we have about 15 minutes left that we can spend we basically describe the high level interface of how this works and they'll touched a little bit about the mass of how rewards are distributed so most logic is happening in internals what uh would be a good way to start like what what should we try to see maybe maybe we can start with internal pink so this is the way that rewards are distributed so let me uh this is a lot of a lot of code to take in without seeing execution if your mic is pretty oh sorry about that thanks josh this is a lot of code to take in without seeing execution is is there if we run like the test suite or some of the tests can we visualize some of the paths through this code like this is what the owner would do when they set things up but this is what you know somebody would do when they're staking in terms of like i don't know like a couple of scenarios to help us exercise our thinking in terms of how this code actually runs does does that make sense right i think um yeah we can do this but it's probably like we'll take some amount of time but uh okay that's right we basically also have simulation tests for this particular pool and maybe well there's not that many but so this simulation test that's like how that network actually gonna work so we first initialized the pool and then um the owner paused the pool we checked well that's not really helpful but the idea is how it works is so bob is the delegator bob called pull deposit which is deposit the amount using deposit method then bob can verify the state balance is working then bob's takes the amount there's um the amount of stake now we verified that the bob has take the same amount not calls the ping there's no rewards but in simulations the rewards are not working anyway so you need to manually do this we'll verify that that bob amount is still the same then pull resumes we verify that the pool has resumed the load to zero then we simulate that the pool has acquired some rewards one and bob pinks the pool and we verify that the amount that bob received is positive that's very like simple simulation case which saying bob first deposited to the pool that verifies that the piles and resume works or simulates that it works and make sure that the pool doesn't stake during while being paused and then when resumed the pull actually stakes so this test verifies not only this but also that bob has acquired reward and got distributed the reward um there's another test that verifies some logic but that's more complicated there are some unit tests on the bottom of this that's supposed to verify certain stuff so let's see what simple one it might be good enough that we just called them out as well that's fine we can take so some of these tests they are not ideal but they verify certain stuff that was good enough to make sure that mass adds up so internal pink is the method that you call or anyone can call actually like through pink to make sure rewards are distributed so right now we have active staking pools and there's a contract or there's a account sponsored by one of uh near folks that basically pings every stake in pool like every 15 minutes to make sure they have distributed the rewards to display on the balance so the way rewards distribution works in the following we first check the current epoch height so if epoch height is the same then the epoch hasn't changed we return false so you don't need to restate but if epoch has changed then we remember that the current epoch exists we get the new total balance of the account um pink may be called when some tokens were deposited through deposit ballots and they already partnered there that pink is called before so we need to subtract this balance before we distribute the rewards so we get the total amount that the account is has including both locked balance and unlocked balance so lock balance is a staked amount that acquires rewards unlocked balance is the it also may have rewards in certain scenarios where you decrease your stake but your rewards will still be reflected for the next two epochs and they will come to them and state them out we verify this is the assert that the total balance is more than the previous total balance this invariant that the stake can pull is requires and there was a bunch of stuff on testnet that happened to fail this invariant because people still had access key on the same staking tool and when you have it you spend the balance for gas and you may decrease your total balance without acquiring the reward finally we calculate the amount of reverse that the stake input received this is total balance minus the previous known total balance so the balance from the previous epoch and if the rewards are positive we distribute them the first thing we do we calculate the reward that the owner takes for themselves as a commission so we multiply this fraction by the total reward received and this is fairly similar rounded down numerator in u256 multiplied by value divided by denominator and u256 so this is the amount in the octane year that the owner will keep for themselves and this is the remaining rewards we're saying all the remaining rewards have to be restaked and it goes here to be restaked then we calculate how many so so owner received the rewards in yocta near not in shares but because all the logic has to be in shares essentially the owner of the staking pool purchases shares at the price of at the price at which the post reward distributions to the rest of the delegators and this is the number of share that owner will receive as a compensation for running the sticking pool if it's positive we increase the amount of shares and save the owner account back and we also increase the total amount of stake in shares if for some reason around and down this balance became zero so reward was very small and the price per share was very large and only received zero rewards then um then this balance will just go to the price per share instead of compensating the owner and finally we put some total login data saying the the current type of exists we received the rewards in that amount of staking shares or in tokens the now the total stake balance of the pool is this and number of shares this is the only way we expose the number of shares to external world is through the logs is this and if uh owner received rewards is saying total reward he was so many shares and finally we just remember the new total balance and that's it so we distributed all rewards in a constant time we only updated one account and this is the owner's account for commission and only if the commission was positive so what else would be interesting here um the interesting part probably is something like a steak or a steak let's see for example a staking thing so the wave is taken that is when we do price guarantee fund is let's say the predecessor in this case we're going to call it account id wants to take this amount of tokens and balance is actually not a json type because it's internal methods we don't need json here we calculate how many shares around it down again down not up required to use take the given amount so this is how many shares the owner owner will receive it has to be positive then we check the amount how much the owner should pay for the shares again round it down this is to guarantee that the owner when they purchased shares and converted back without rewards never lost the one yoktan year because it might break the current team finally the same that the account has enough amount to pay for the amount charged and we give the unstaked we decrease the internal and state balance increase the internal number of shares balance of the account and the stake amount we round this up so the number of shares actually rounded up so this one extra penny or like one extra yak 10 year will come from the guaranteed fund during the rounding of the shares up so we charge user less but we contributed to the amount more from this one trillion yaktas that we had originally designated for this and this uh difference usually is just one yoctaner that may come from rounded up or down and this is the amount of total stake balance and number of shares increasingly minted new shares finally we put a log and return and unstaking works very similarly you round up to this amount of shares you need to pay we calculate how much amount you receive again rounding up to be overpaying you for this but this also comes from guaranty fund and we decrease the shares to increase the amount and saying when you can unlock between four epochs and this is downstate amount to the rounded it down so we understand slightly less to guarantee the price of other participants of the pool so that's pretty much how the staking pool works and how mass works we compensate for rounding errors from from the font that we allocated okay i think um the amount of time that we wanted to spend on this and we can do a few questions and then finish it up let me know if you have i've got a pile of questions but i've been talking a lot so i'll wait a few seconds to see if anybody else wants to ask okay yeah okay go ahead okay i'll just fire off the questions then you can decide what you want to answer okay um just an in order of of how these occurred to me uh while you were talking um so uh you mentioned ristretto keys are required for validators or validator nodes i was wondering why that is it seems like there's some kind of subset of uh the curve keys that are somehow more secure based on what i checked out briefly i'm not quite sure if you can add to that does this stake share price guarantee fund set an upper limit on the lifetime of the contract or does that get like refilled over time those are like the two maybe technical questions and then two questions around like a level of effort and experience review like a retrospective on this work like level of effort like how long did this take to design and build how many people were involved how many revisions were there and then for experience like what was the hardest part of this for you what was the most surprising any discoveries that you made any changes that were put into the protocol like during the development of this because of its development that kind of stuff all right so so for strata it's pretty much yes so we updated it during the design of this um contract and that was a surprise that we needed to account for this um then second was about the price guarantee so one trillion should be enough for like half like 500 billion transactions so that should be long enough for the staking pool so it cannot be refilled because the rewards will be immediately redistributed to the total stake balance on the next ping um so it's a lifetime of the contract i say but it's unlikely to happen um next was the question about the level of expertise i think we spent on this contract quite a bit because and we did tons of security reviews including like internally and externally especially around this mass that was complicated some stuff was discovered like this or strata key popped up during the reviews so we marked the change lock of this contract as well in the readme there there's a bunch of stuff that popped up during the development and testing on the live system but the original version was um it took maybe like a week to write and later like clean it up test it properly and improve and then we did a bunch of revisions so pausing and resuming was asked by the pool because otherwise the owner had no ability to unstake and if their node goes down they will be attacking the network essentially this active stake kind of requesting the validation and not running the network so right now we don't have slashing so this was just not an issue for the participants but it will it was an issue for the network itself so that way the owner can pause the staking and just if they don't want to run the pool they migrate into the pool and communicate as much as possible before this next we updated the vote interface to match the final phase two voting contract those helper view methods and to be able to query accounts in a human readable way and finally there was some improvements around batching methods together so deposit mistakes they call and stay call withdrawal instead of like you have to make a view call first get them uh put them out to call the stake and the way we fixed it i think you can spend a few minutes on this when you stake not only you take the amount we also attach a promise to check if the stake was successful it needed for two things so you if you're trying to stick with invalid key not restricted specific key then the promise before execution will fail so it will fail validation before sending it and that will make it uh so this way you don't need to check it within the contract it will revert the last call and it's all gonna be good but we also introduced the minimal seat on the contract and the minimum not not minimum minimum stake on the protocol level so minimum stake is one tenth of the amount of last seed price and if your contract tries to stake less than this then the action will fail and you will not send the prop so let's say you want to unstake some amount and you dropped your balance below one tenth of the stake so the stake in action may fail and you will not understate while you need it to guarantee that on stake infested it has to happen in this case we have this callback on that checks that the stake in action has successfully completed and this callback it basically checks that if it fails if it fails and the balance is positive we need to unstake so it will call and stake an action where the stake amount to zero to make sure that the all balance is released and you can withdrawing for epochs and just standings during the testing of these contracts that we did on the beta 9 test notes before maintenance so it took like uh the contract was ready maybe around the summer time so the testing of this iteration of this took probably like two three four months due to complexity that it involves uh interacting with the protocol and as for learning so quite a lot of learning so from pagination to helper methods and batching together some stuff so one thing that would be really nice to have is take or like deposit and stake all on a lock-up contract so right now lockup you have to issue manually how much you want to stake on a local contract but it would be great that you didn't need to think about your year how much it's locked for storage and stuff like this and just you want to stake everything from your locker but because it was already deployed it was too late to think about this there's also some gas that is hardcoded and this the common decrease in fee this this numbers cannot be changed because they're already on chain the world is not important but this method requires you to have a large number for every stake actually and you cannot decrease it so every like risk taking action on every call on this contract will require us to have a large amount of gas and the problem is that that's wasteful it's wasteful uh we had a proposal to burn all the gas that you attach and in this case once the heat goes down and we decide let's say we agree on burning all the gas this gas will be always burned like wasted plus it like limits the number of transactions you can put into one block because of the that gas amount if we are restricting based on this case finally there was like lots of iteration on the testing of the contract using the simulation test framework that we improved a lot and from this learning if we get to the lock-up contracts eventually you can see how the structure of local contracts improved over this one and like there's a better structure on this forces so like we split all the methods there's getters internal owners method foundation methods types utilities so this is still bundled together but it was a good iteration and credibility of the contracts plus a lot of stuff was improved on near sdk itself um on nearby gym to to help support some stuff like this public key serialization for example so you don't need to think about how the json string converts into inner 32 bytes representation yeah so that's like a review i think that was more technical than the first one and let us know if you have any feedback and we'll try to improve on it thank you any final comments before this step no okay thanks everyone","transcript_synced_at":"2026-11-04T04:23:36.619Z","segments":[{"start_seconds":4,"text":"hey i'm eugene and i'm here with mike sheriff chad and josh and this is the second episode of live","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=4s"},{"start_seconds":12,"text":"contract reviews and today we're gonna review stake staking pool contract which is used right now to secure","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=12s"},{"start_seconds":20,"text":"near protocol proof of stake system basically all validators that currently","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=20s"},{"start_seconds":29,"text":"are running on your protocol are running on behalf of the contract so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=29s"},{"start_seconds":37,"text":"they don't control the account themselves that stakes the amount for proof of stake but instead the contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=37s"},{"start_seconds":44,"text":"stakes this amount and they just provide a staking pool and they run their","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=44s"},{"start_seconds":51,"text":"nose and today we're gonna dig into this contract and let me present my","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=51s"},{"start_seconds":59,"text":"window all right um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=59s"},{"start_seconds":69,"text":"so i hope you can see it so in the core contracts we have a stake in pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=69s"},{"start_seconds":78,"text":"account or a stake in pool contract and it's a little more complicated than the previous contract that we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=78s"},{"start_seconds":87,"text":"reviewed the voting contract so today we're going to focus more on the logic","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=87s"},{"start_seconds":93,"text":"and less on the near bench and russ specific stuff but it will probably involve a little","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=93s"},{"start_seconds":101,"text":"more of a near protocol knowledge so as before","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=101s"},{"start_seconds":111,"text":"the contract starts um from the main structure in this case it's a stake in contract structure as you can see there's a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=111s"},{"start_seconds":119,"text":"nearby gene and burst direct of more serialized serialize and the structure now has way more field","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=119s"},{"start_seconds":127,"text":"than the past and there are some comments on them probably most of them are up to date the logic of the staking pool contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=127s"},{"start_seconds":137,"text":"allows to do the following basically anyone can deposit some amount of near tokens","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=137s"},{"start_seconds":146,"text":"to the staking pool and delegate them to the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=146s"},{"start_seconds":153,"text":"by staking on the pool that allows to bundle together balances from","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=153s"},{"start_seconds":161,"text":"multiple people we call them accounts here into one large","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=161s"},{"start_seconds":170,"text":"stake and this way this large state may actually","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=170s"},{"start_seconds":179,"text":"qualify for validator sheets and your protocol has a limited amount of seats right now for a single chart","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=179s"},{"start_seconds":187,"text":"there's at most hundred validator seats you can think about the cities if you take the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=187s"},{"start_seconds":195,"text":"total amount of token staked and divided by 100 the minimum so this number will be a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=195s"},{"start_seconds":204,"text":"minimum amount required for a single seat something like this except it's a little","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=204s"},{"start_seconds":212,"text":"bit more complicated to involve removing the stakes that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=212s"},{"start_seconds":219,"text":"are not qualified to do this minimum amount and stuff like this but this contract basically is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=219s"},{"start_seconds":229,"text":"a contract standalone contract without any exit key on it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=229s"},{"start_seconds":237,"text":"that is controlled by the owner in this case owner is provided into initialization so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=237s"},{"start_seconds":244,"text":"let's go to initialization method similar as before it has three arguments and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=244s"},{"start_seconds":254,"text":"first is owner id owner id is the account id of the owner account","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=254s"},{"start_seconds":262,"text":"and owner has a bunch of permissions on this contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=262s"},{"start_seconds":268,"text":"that allowed the contract to um to perform","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=268s"},{"start_seconds":276,"text":"actions that are not available for the rest of the accounts so if their account","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=276s"},{"start_seconds":286,"text":"and one of these methods was to vote vote on behalf of the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=286s"},{"start_seconds":294,"text":"to the voting contract that we'll discuss last time so the owner can call world","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=294s"},{"start_seconds":308,"text":"um vote method we verify that the predecessor equals to the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=308s"},{"start_seconds":317,"text":"owner so this method uh can only be called by the owner","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=317s"},{"start_seconds":325,"text":"so welcome bone to joining our meeting so at this meeting we basically uh go","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=325s"},{"start_seconds":332,"text":"through a contract and we record it and later we publish it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=332s"},{"start_seconds":339,"text":"so the community can see the logic and understand how the contracts are implemented","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=339s"},{"start_seconds":346,"text":"on near specifically rust contracts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=346s"},{"start_seconds":352,"text":"so the vote method is first thing it does it verifies that the method was only called by the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=352s"},{"start_seconds":360,"text":"owner and then it verifies that some logic but that's not important right now","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=360s"},{"start_seconds":369,"text":"so the contract is the owner and this owner can do certain things so it has the extra permissions","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=369s"},{"start_seconds":377,"text":"then it takes a few more fields it's taking stake public key so when you","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=377s"},{"start_seconds":384,"text":"stake on your protocol you need to provide a public key that will be used","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=384s"},{"start_seconds":392,"text":"by your validator node to to sign messages on behalf of the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=392s"},{"start_seconds":401,"text":"validator node and this public key can be different from any","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=401s"},{"start_seconds":408,"text":"access key and ideally it should be different from any access key because your node may be run in a data","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=408s"},{"start_seconds":417,"text":"center that can be vulnerable to some attacks and in this case the most they can do is actually do something bad to the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=417s"},{"start_seconds":425,"text":"network but not to your account and they cannot steal your fonts and you can replace this key easily comparing to you need to like","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=425s"},{"start_seconds":435,"text":"replace the bad access key and finally the third argument that the contract takes is initial reward","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=435s"},{"start_seconds":443,"text":"fee for action so this is the commission that the owner of the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=443s"},{"start_seconds":451,"text":"takes on on for running the validator node","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=451s"},{"start_seconds":458,"text":"and this is a fraction that has numerator and denominator","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=458s"},{"start_seconds":466,"text":"and it allows you to basically say for example i take one percent of the rewards for running this particular pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=466s"},{"start_seconds":476,"text":"and if let's say you have a million tokens they acquired some reward let's say 10 000 tokens in your work","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=476s"},{"start_seconds":484,"text":"then the owner will take one percent out of this which is 100","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=484s"},{"start_seconds":491,"text":"can i ask tokens quick question yes um so i've heard this in discord before um people wondering","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=491s"},{"start_seconds":498,"text":"about using floats um and maybe can we talk a little bit about why we have a numerator and denominator um for this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=498s"},{"start_seconds":506,"text":"kind of percentage stuff right so floats which has an unpredictable behavior when","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=506s"},{"start_seconds":514,"text":"you multiply them and you acting on the floats while this piece is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=514s"},{"start_seconds":520,"text":"can be for fractions for example you can use","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=520s"},{"start_seconds":526,"text":"a math with larger number of bits so the way you for","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=526s"},{"start_seconds":534,"text":"example do division is you first multiply the amount which is u128 by this numerator","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=534s"},{"start_seconds":542,"text":"and this already can overflow u128 but that's why we do this in u256 and then you divide it by the denominator","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=542s"},{"start_seconds":551,"text":"which should bring it below u128 again","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=551s"},{"start_seconds":559,"text":"which gives you higher precision than for example flood 64 that cannot operate","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=559s"},{"start_seconds":567,"text":"with you 128 bits precision so it will have some rounding errors like precision errors when you do","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=567s"},{"start_seconds":575,"text":"the mass so you either need like a higher precision floats which are not really different from the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=575s"},{"start_seconds":583,"text":"mass we simulate this u256 does this make sense cool yeah thank you also","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=583s"},{"start_seconds":592,"text":"i think solidity originally doesn't support floats and we originally also did not support","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=592s"},{"start_seconds":602,"text":"floats but that cast some issues around string formatting and rust for debugging","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=602s"},{"start_seconds":610,"text":"so we decided that there is no harm in supporting floats especially as we standardize this on the vm side so biggest issue with","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=610s"},{"start_seconds":620,"text":"slot was undefined behavior around like certain values of loads like what","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=620s"},{"start_seconds":626,"text":"means for example when you have infinite flow to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=626s"},{"start_seconds":634,"text":"what other beats uh contain so we standardize this and now they are equivalent platform","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=634s"},{"start_seconds":641,"text":"independent so it's okay to use plots now in","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=641s"},{"start_seconds":648,"text":"our vm environment so again standard practice this in it is we first check that the state doesn't exist","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=648s"},{"start_seconds":657,"text":"then we verify input up to certain things that we can do so first thing we do we verify that the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=657s"},{"start_seconds":665,"text":"fraction is valid and we check that denominator is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=665s"},{"start_seconds":672,"text":"not zero and else numerator is less than equal than denominator which makes a fraction is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=672s"},{"start_seconds":680,"text":"less than equal to one this is important to avoid some logic","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=680s"},{"start_seconds":688,"text":"mistakes next thing we do is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=688s"},{"start_seconds":696,"text":"we verify that the account is valid so this contract was written before some of the helper metric exists so now we have for example","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=696s"},{"start_seconds":705,"text":"valid account id in json types that does this check automatically during the decentralization","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=705s"},{"start_seconds":714,"text":"and if it's invalid it will just panic next thing we do we pull the account balance the current account balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=714s"},{"start_seconds":723,"text":"of this taking contract so this balance has to is usually large enough because it has","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=723s"},{"start_seconds":731,"text":"to pay for the storage of this particular contract and then we say","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=731s"},{"start_seconds":737,"text":"we gonna allocate some tokens for price guarantee fund","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=737s"},{"start_seconds":744,"text":"so the staking pool has certain guarantees that are important for local contracts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=744s"},{"start_seconds":752,"text":"and guarantees are when you deposit to the staking pool you should be able to withdraw at least","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=752s"},{"start_seconds":759,"text":"the same amount of tokens and you cannot lose tokens even like one yacht and year on this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=759s"},{"start_seconds":767,"text":"contract by depositing and withdrawing from the staking pools","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=767s"},{"start_seconds":775,"text":"so this uh stake share price guarantee fund is around and around 1 trillion","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=775s"},{"start_seconds":783,"text":"yocton year which we consume usually around one or two yuctan year","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=783s"},{"start_seconds":790,"text":"for rounding errors and we can get into details of how this works and finally we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=790s"},{"start_seconds":800,"text":"remember what's the balance that we're gonna stake on behalf of this contract itself this is required to establish some baseline","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=800s"},{"start_seconds":808,"text":"to limit the rounding differences and we verify that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=808s"},{"start_seconds":816,"text":"the account doesn't stake already so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=816s"},{"start_seconds":825,"text":"this might break some logic and we don't want this to happen so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=825s"},{"start_seconds":835,"text":"we want to initialize the contract before it stakes anything finally we initialize the structure but","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=835s"},{"start_seconds":842,"text":"we don't return it immediately we just created the structure here","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=842s"},{"start_seconds":854,"text":"and then we issue a risk-taking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=854s"},{"start_seconds":862,"text":"transaction this is important because we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=862s"},{"start_seconds":869,"text":"make sure that this taken key that was provided is a valid rosette","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=869s"},{"start_seconds":876,"text":"restricted eg 250 or 25 something like 5 119","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=876s"},{"start_seconds":885,"text":"valid key so there are some keys on the curve that are valid","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=885s"},{"start_seconds":893,"text":"keys but not restricted specific and validators keys can only be restrata","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=893s"},{"start_seconds":901,"text":"specific so this is a near protocol specific scene and what happens is it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=901s"},{"start_seconds":908,"text":"makes a staking transaction this is the given key and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=908s"},{"start_seconds":917,"text":"once this transaction is created from the contract when it leaves we do validation on this transaction","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=917s"},{"start_seconds":924,"text":"and if the key is invalid then it will throw an error and entire sync initialization of this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=924s"},{"start_seconds":932,"text":"taken pool will fail so if you pass invalid staking key public key","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=932s"},{"start_seconds":938,"text":"as an input then your contract consolidation and deployment and all this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=938s"},{"start_seconds":946,"text":"that happens in one batch transaction will be reverted and this is important so the pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=946s"},{"start_seconds":953,"text":"doesn't have an invalid key because that might be allowing you to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=953s"},{"start_seconds":960,"text":"block the stake of other people and we don't wanna so as part of guarantees we're saying if","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=960s"},{"start_seconds":967,"text":"you're on stake your tokens will be returned in four epochs","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=967s"},{"start_seconds":974,"text":"so they will be eligible for withdrawal this is again important for lockups","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=974s"},{"start_seconds":981,"text":"um to be able to return them to lookups i think this is too much details be","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=981s"},{"start_seconds":988,"text":"before i explain the high level of how contract works and how balances works so we should probably go","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=988s"},{"start_seconds":999,"text":"here and explain the concept of how we actually can","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=999s"},{"start_seconds":1006,"text":"distribute rewards to account owners in a constant time when","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1006s"},{"start_seconds":1014,"text":"an epoch passes so this is important for most of the smart contracts they want to act","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1014s"},{"start_seconds":1022,"text":"in a constant time for every method instead of a linear time for the amount of users","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1022s"},{"start_seconds":1029,"text":"because if the amount of users grow then the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1029s"},{"start_seconds":1038,"text":"um the amount of gas required to operate a linear scale will grow as well and eventually will run out of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1038s"},{"start_seconds":1046,"text":"gas so that's why all smart contracts have to act in","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1046s"},{"start_seconds":1053,"text":"a constant time usually algorithmic so the way it works for every user we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1053s"},{"start_seconds":1062,"text":"keep structure called account so every user that delegated to this speaking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1062s"},{"start_seconds":1069,"text":"will have a structure called account that has the following fields","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1069s"},{"start_seconds":1078,"text":"and staked is the balance in the octane year that is not staked so it's just a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1078s"},{"start_seconds":1086,"text":"balance of the user then stake shares is actually a balanced","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1086s"},{"start_seconds":1094,"text":"but not in near but instead in a number of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1094s"},{"start_seconds":1102,"text":"stake shares so stake share is a concept that was added to this particular staking pool and the way it works","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1102s"},{"start_seconds":1110,"text":"is when you state you buy you essentially","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1110s"},{"start_seconds":1118,"text":"mean new shares at the current price by converting your on state balance into stake shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1118s"},{"start_seconds":1126,"text":"so a stake share price originally is one but over time it grows with rewards","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1126s"},{"start_seconds":1134,"text":"and when the account receives rewards its uh total stake balance increases but","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1134s"},{"start_seconds":1142,"text":"the amount of total stake shares doesn't change so essentially when an account receives","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1142s"},{"start_seconds":1151,"text":"validation rewards or some other deposits straight to the balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1151s"},{"start_seconds":1160,"text":"that increases the amount that you can receive for every state","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1160s"},{"start_seconds":1167,"text":"share so the example can be the following","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1167s"},{"start_seconds":1175,"text":"let's say you had originally one million year that was deposited to this account","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1175s"},{"start_seconds":1184,"text":"let's say you get one million shares ignoring the yorkton year for now now if this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1184s"},{"start_seconds":1191,"text":"token if the staking pool received um 10 000","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1191s"},{"start_seconds":1199,"text":"near in reward you still have 1 million shares but this 1 million","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1199s"},{"start_seconds":1206,"text":"shares now corresponds to 1 million and 10 000 year","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1206s"},{"start_seconds":1213,"text":"now if someone else wants to stake at this time they will purchase stake shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1213s"},{"start_seconds":1222,"text":"internally within the contract at the price of um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1222s"},{"start_seconds":1232,"text":"1.001 that is because every share now is equal to 100","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1232s"},{"start_seconds":1242,"text":"1 year now when you receive another reward","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1242s"},{"start_seconds":1252,"text":"you don't need there's the total balance and in the constant time everybody share the reward","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1252s"},{"start_seconds":1261,"text":"proportionally to the number of shares they have now when you're on state you're essentially selling these shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1261s"},{"start_seconds":1270,"text":"or burning them in concept of fungible tokens in favor","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1270s"},{"start_seconds":1278,"text":"of unstaked balance so you sell at the current price so you decrease the total amount of stake","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1278s"},{"start_seconds":1285,"text":"as well as total amount of shares and when you purchase you increase the total","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1285s"},{"start_seconds":1292,"text":"stake balance and the total stake shares while keeping the price at the constant so when you buy or","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1292s"},{"start_seconds":1300,"text":"like when you stake on stake you don't change the price when you receive the reward you increase the price","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1300s"},{"start_seconds":1308,"text":"so the price can only go up uh so this may lead to the rounding","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1308s"},{"start_seconds":1315,"text":"errors when you have when your yoked and your balance cannot correspond precisely","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1315s"},{"start_seconds":1322,"text":"and that's why we have this guarantee fund of like 10 trillion or like 1 trillion yak 10","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1322s"},{"start_seconds":1330,"text":"years that will throw one extra yokta a few times","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1330s"},{"start_seconds":1336,"text":"and finally the final part is because the near protocol does not","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1336s"},{"start_seconds":1345,"text":"unstake and return the balance immediately it has to wait three epochs until your balance will became","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1345s"},{"start_seconds":1354,"text":"unstaked and returned to the account so unlocked so if you're on stake you cannot withdraw","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1354s"},{"start_seconds":1362,"text":"this balance immediately from the staking pool you need to wait three epochs","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1362s"},{"start_seconds":1369,"text":"and do you remember at which epoch height you called","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1369s"},{"start_seconds":1379,"text":"the last and stake action and after interior three e-books","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1379s"},{"start_seconds":1387,"text":"your balance will became unlocked and you should be able to withdraw from one state","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1387s"},{"start_seconds":1395,"text":"but there's one caveat resist if you call and state at the last block","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1395s"},{"start_seconds":1403,"text":"of the epoch the actual promise that does unstaking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1403s"},{"start_seconds":1411,"text":"will arrive for the next epoch first block of the next epoch and that will delay your","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1411s"},{"start_seconds":1424,"text":"uh locked balance to become unlocked for four epochs instead of three because","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1424s"},{"start_seconds":1431,"text":"we recorded the e-book in the previous block but the actual transaction happened in the next block","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1431s"},{"start_seconds":1438,"text":"on the next epoch and to make sure that doesn't happen we log the balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1438s"},{"start_seconds":1447,"text":"by four e-books instead of three e-books to account for this border case","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1447s"},{"start_seconds":1456,"text":"so that's an account um does it make sense so far of like how the high-level logic works","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1456s"},{"start_seconds":1464,"text":"from stake and stake shares yeah okay so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1464s"},{"start_seconds":1472,"text":"let's uh i've i've got a couple of questions but i don't know if this is the right place for them like in terms of the yeah you decide in","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1472s"},{"start_seconds":1481,"text":"terms of the design of this was this pre-designed or for example num stake shares and this kind of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1481s"},{"start_seconds":1488,"text":"you know simplification of having you know internal uh shares that people buy into at different periods sometimes you know people will make a design","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1488s"},{"start_seconds":1497,"text":"choice like that to to simplify a bunch of kind of noise you know arithmetic noise or whatever that's spread around the code and you kind of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1497s"},{"start_seconds":1505,"text":"factor it out into this new idea that makes things easier or did you kind of start with this idea i i'd be curious like like when","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1505s"},{"start_seconds":1514,"text":"and how some of these decisions were made what the the um the kind of the driver was to make the decision because that might help uh developers recognize those moments in","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1514s"},{"start_seconds":1522,"text":"their own code and say oh yeah i kind of run into the same problem maybe i should do this or that right so i think well the idea of shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1522s"},{"start_seconds":1532,"text":"is not that new because on ethereum majority of like providers liquidity providers and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1532s"},{"start_seconds":1539,"text":"automated market makers use this similar concept so when you for example um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1539s"},{"start_seconds":1548,"text":"deposit to the liquidity pool you get some kind of token from this tool instead of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1548s"},{"start_seconds":1556,"text":"actual amount of um that represented there and when you withdraw from the pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1556s"},{"start_seconds":1562,"text":"located pool then you burn this token and get the actual represented tokens so the idea is very","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1562s"},{"start_seconds":1570,"text":"similar to to call them shares is somewhat","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1570s"},{"start_seconds":1577,"text":"because they have a corresponding price so we could have called them differently","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1577s"},{"start_seconds":1584,"text":"it was almost from the beginning of this taking pool contract because we needed a way to represent","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1584s"},{"start_seconds":1593,"text":"well not really like there was exploration around how we can do this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1593s"},{"start_seconds":1600,"text":"properly and one way was we limit the number of accounts that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1600s"},{"start_seconds":1607,"text":"can deposit to a given pool to account for this particular update and eventually we landed on","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1607s"},{"start_seconds":1616,"text":"the constant time and it was actually simpler model constant complexity time","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1616s"},{"start_seconds":1627,"text":"and then the mass of this became somewhat reasonable even so there's some","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1627s"},{"start_seconds":1634,"text":"complexity as well involved there so let me probably go through","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1634s"},{"start_seconds":1643,"text":"this contract it's not as well structured as for example a lock-up contract because lockup isn't even more","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1643s"},{"start_seconds":1650,"text":"complicated so the types are still bundled in the same contract so there is a bunch of types of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1650s"},{"start_seconds":1658,"text":"for example revolt fraction is a separate type um account is a separate type","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1658s"},{"start_seconds":1667,"text":"and there's also a human readable account there's a type that only used for","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1667s"},{"start_seconds":1674,"text":"view calls so it's not used for logic internally","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1674s"},{"start_seconds":1683,"text":"then after you finish with all the types we have a cross contract calls using a high level interface","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1683s"},{"start_seconds":1695,"text":"so there's two of them the way it works is you have a macro","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1695s"},{"start_seconds":1702,"text":"from nearby engine called x contract standing for external contract you can give a short name that it will generate","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1702s"},{"start_seconds":1710,"text":"that you will be able to use and then you have a trade description describing the interface of external contract that you","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1710s"},{"start_seconds":1719,"text":"want to do and this describes that you can call a meta vote on a remote contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1719s"},{"start_seconds":1727,"text":"and pass one argument which is is vote true or false bullying","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1727s"},{"start_seconds":1733,"text":"now you will be able to create a promise when you need it and pass a positional argument instead of a json serialized argument","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1733s"},{"start_seconds":1742,"text":"and the macro behind the synth will make it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1742s"},{"start_seconds":1749,"text":"into low-level promise apis and the second interface for a callback on ourselves so this is fairly comp","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1749s"},{"start_seconds":1759,"text":"common you can call it excel so when you need to do a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1759s"},{"start_seconds":1765,"text":"callback and do something on on the result of the asynchronous promise you can","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1765s"},{"start_seconds":1773,"text":"have this type of interface and what we do we check if this taken","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1773s"},{"start_seconds":1780,"text":"action succeeded and we'll may get to this detail if it's","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1780s"},{"start_seconds":1787,"text":"we have time so finally we have this main implementation structure um implementation body of the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1787s"},{"start_seconds":1797,"text":"so we went through the constructor so the next um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1797s"},{"start_seconds":1805,"text":"method so this contract is split into multiple modules so you have um so this is a liberals which is the main","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1805s"},{"start_seconds":1814,"text":"input and now also you have internal module the internal module has the implementation without","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1814s"},{"start_seconds":1824,"text":"um nearby macro so none of these methods will be visible to be called by","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1824s"},{"start_seconds":1833,"text":"a contract by someone else on the chain they only can be called within this contract internally so they don't generate","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1833s"},{"start_seconds":1841,"text":"json formats and don't deserialize state so they all act as a regular rust","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1841s"},{"start_seconds":1849,"text":"methods so the way inter","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1849s"},{"start_seconds":1857,"text":"again high level how this contract works is when an epoch passes you may acquire","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1857s"},{"start_seconds":1864,"text":"certain rewards the as a validator so we have a method","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1864s"},{"start_seconds":1871,"text":"ping which pings the contract so method checks if the there's","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1871s"},{"start_seconds":1878,"text":"e-podcast and then we need to distribute rewards","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1878s"},{"start_seconds":1885,"text":"and we'll go there for the logic later and if ebook change then it will also","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1885s"},{"start_seconds":1892,"text":"restate because the there might be some change in the amount","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1892s"},{"start_seconds":1899,"text":"of total stake the contract has to take the next is deposit","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1899s"},{"start_seconds":1908,"text":"deposit is a payable which means it can accept an attached deposit so this is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1908s"},{"start_seconds":1916,"text":"similar to ethereum um decorator that allows to receive fonts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1916s"},{"start_seconds":1923,"text":"only to the methods that expect them so nearby gen by default will panic if you try","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1923s"},{"start_seconds":1930,"text":"to call a method for example pink and attach a deposit to this method","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1930s"},{"start_seconds":1938,"text":"and payable allows to attach deposit so every method","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1938s"},{"start_seconds":1947,"text":"there's a internal pink to make sure we distributed previous rewards before changing any logic","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1947s"},{"start_seconds":1956,"text":"and the common structure is if we need to restake then we first do some logic and then restake","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1956s"},{"start_seconds":1965,"text":"so this is next methods depositive stake this combination between","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1965s"},{"start_seconds":1972,"text":"two methods of like first you deposit balance to the state balance of your account and also you want to stake the same amount","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1972s"},{"start_seconds":1980,"text":"immediately instead of doing two transactions it's also payable because it also accepts a deposit","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1980s"},{"start_seconds":1988,"text":"so next is withdraw all withdraw all uh tries to withdraw all","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1988s"},{"start_seconds":1996,"text":"entire unstate balance from the account that called it so when you call or when you interact","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=1996s"},{"start_seconds":2003,"text":"with the staking pool you need to interact with the account that is owns the balance so in this case this is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2003s"},{"start_seconds":2013,"text":"a predecessor account id and the logic is we basically check the account","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2013s"},{"start_seconds":2019,"text":"and then we this draw dance take them out if we can and if it's not then it will panic for example if it's still locked due to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2019s"},{"start_seconds":2028,"text":"unstaking for epochs ago lesson for epoxy this draw allows to withdraw the balance that is not","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2028s"},{"start_seconds":2038,"text":"not all balanced but only partial balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2038s"},{"start_seconds":2044,"text":"then stake all is um stakes all unstaked balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2044s"},{"start_seconds":2052,"text":"and it's pretty rare to have this method because you usually use depositing stake and it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2052s"},{"start_seconds":2058,"text":"already has all the steak balance then steak you just take some amount of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2058s"},{"start_seconds":2067,"text":"steak balance i think moonlight wallet uses separate cost to deposit in steak but they use a batched","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2067s"},{"start_seconds":2074,"text":"transaction to do this finally you have one","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2074s"},{"start_seconds":2082,"text":"stakehold it's on stakehold it takes your current amount in","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2082s"},{"start_seconds":2090,"text":"um so it basically unstakes all your stake shares by converting them","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2090s"},{"start_seconds":2097,"text":"to your tenure so this is the helper method which saying convert my","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2097s"},{"start_seconds":2107,"text":"shares number of shares to amount","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2107s"},{"start_seconds":2114,"text":"to yoktan near amount and round down because we cannot give you extra for","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2114s"},{"start_seconds":2122,"text":"your share multiplied by price and that's how we get the amount and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2122s"},{"start_seconds":2130,"text":"then we call and stake for the given amount so this logic is the following","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2130s"},{"start_seconds":2139,"text":"it uses u256 because we operate balances","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2139s"},{"start_seconds":2146,"text":"operate on u128 and to avoid overflow we do the following we multiply the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2146s"},{"start_seconds":2154,"text":"balance by number of shares so basically this is the price","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2154s"},{"start_seconds":2160,"text":"this two divided and rounding down and equivalent is we have a round up","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2160s"},{"start_seconds":2170,"text":"but it's reverse and it's uh state amount round it up here's a round up","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2170s"},{"start_seconds":2177,"text":"roundup is very similar except we do this check that allows to round up and then","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2177s"},{"start_seconds":2186,"text":"we cast it back to you 128. okay so this one stay called then we have a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2186s"},{"start_seconds":2196,"text":"stakeout action which is very similar to unstable except you pass the amount and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2196s"},{"start_seconds":2204,"text":"then there's a bunch of getter methods that view calls that return you some amounts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2204s"},{"start_seconds":2211,"text":"so you can get the state balance state balance total balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2211s"},{"start_seconds":2217,"text":"check if you can withdraw then you can get total stake balance this is the total amount the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2217s"},{"start_seconds":2225,"text":"staking pool has inactive stake then you can get who is the owner","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2225s"},{"start_seconds":2233,"text":"of the staking pool you can get the current reward fee or commission of the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2233s"},{"start_seconds":2240,"text":"get the current staking key and there's a separate thing that allows the owner to pause the station","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2240s"},{"start_seconds":2249,"text":"from let's say the owners does a migration on the staking pool on the node so something","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2249s"},{"start_seconds":2258,"text":"they need to completely unstake for example so they can pause the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2258s"},{"start_seconds":2265,"text":"which will send a state transaction to the near protocol","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2265s"},{"start_seconds":2272,"text":"and then will not restake until until they","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2272s"},{"start_seconds":2281,"text":"resume the staking pool but you can still withdraw your balances but you will stop","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2281s"},{"start_seconds":2288,"text":"acquiring rewards after it's passed finally you can get a human readable","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2288s"},{"start_seconds":2295,"text":"account so it gives you instead of giving you number of shares we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2295s"},{"start_seconds":2302,"text":"give you how much tokens you actually have for the number of shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2302s"},{"start_seconds":2310,"text":"at the current price and finally saying can you withdraw a note then it gives you a number of accounts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2310s"},{"start_seconds":2320,"text":"number of delegators to this taking post and you can also uh retrieve multiple delegators at once so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2320s"},{"start_seconds":2328,"text":"this is a pagination on um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2328s"},{"start_seconds":2335,"text":"on the large number of accounts within the unordered map and the way you do this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2335s"},{"start_seconds":2343,"text":"is one way of doing this is you use the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2343s"},{"start_seconds":2350,"text":"helper that we call keys as a vector from the unaltered map it gives you persistent collection of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2350s"},{"start_seconds":2359,"text":"keys from the map and then you can use iterator to request accounts from these","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2359s"},{"start_seconds":2367,"text":"keys so that's not the most efficient way but it is allows you to implement","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2367s"},{"start_seconds":2376,"text":"visionation on an ordered maps and finally this is the callback that we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2376s"},{"start_seconds":2385,"text":"will probably skip for now and there is a bunch of owners method so owner method is the method that can only be called by","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2385s"},{"start_seconds":2394,"text":"the owner so owner can update the stake input key let's say they have a different node","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2394s"},{"start_seconds":2401,"text":"and need to use a different key so all these methods first check that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2401s"},{"start_seconds":2410,"text":"the only owner could call it this is the method that changes the commission on the staking pool so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2410s"},{"start_seconds":2419,"text":"owner can change the commission that will be active at the at this epoch","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2419s"},{"start_seconds":2427,"text":"starting from this epoch immediately but all the previous commissions will be calculated using the previous fee","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2427s"},{"start_seconds":2435,"text":"then this was a vote that allowed us to transition to phase two of the mainnet and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2435s"},{"start_seconds":2443,"text":"two methods that i described which allowed to pause taking and to resume staking and finally we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2443s"},{"start_seconds":2450,"text":"have tests here so we have","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2450s"},{"start_seconds":2457,"text":"about 15 minutes left that we can spend we basically describe the high level interface of how this works","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2457s"},{"start_seconds":2464,"text":"and they'll touched a little bit about the mass of how rewards are distributed so most logic is happening","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2464s"},{"start_seconds":2473,"text":"in internals","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2473s"},{"start_seconds":2478,"text":"what uh would be a good way to start like what what should we try to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2478s"},{"start_seconds":2487,"text":"see maybe maybe we can start with internal pink so this is the way that rewards are","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2487s"},{"start_seconds":2494,"text":"distributed so let me uh this is a lot of a lot of code to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2494s"},{"start_seconds":2504,"text":"take in without seeing execution if your mic is pretty oh sorry about that thanks josh this is","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2504s"},{"start_seconds":2513,"text":"a lot of code to take in without seeing execution is is there if we run like the test suite or some of the tests can we visualize","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2513s"},{"start_seconds":2520,"text":"some of the paths through this code like this is what the owner would do when they set things up but this is what you know somebody would do when they're staking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2520s"},{"start_seconds":2527,"text":"in terms of like i don't know like a couple of scenarios to help us exercise our thinking in terms of how this code actually runs does does that make sense","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2527s"},{"start_seconds":2536,"text":"right i think um yeah we can do this but it's probably like we'll take some amount of time but uh","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2536s"},{"start_seconds":2546,"text":"okay that's right we basically also have simulation tests for this particular pool and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2546s"},{"start_seconds":2554,"text":"maybe well there's not that many but so this simulation test that's like how","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2554s"},{"start_seconds":2562,"text":"that network actually gonna work so we first initialized the pool and then um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2562s"},{"start_seconds":2573,"text":"the owner paused the pool we checked well that's not really helpful","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2573s"},{"start_seconds":2584,"text":"but the idea is how it works is so bob is the delegator","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2584s"},{"start_seconds":2594,"text":"bob called pull deposit which is deposit the amount using","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2594s"},{"start_seconds":2601,"text":"deposit method then bob can verify the state balance is working","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2601s"},{"start_seconds":2608,"text":"then bob's takes the amount there's um the amount of stake now we verified that the bob has take the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2608s"},{"start_seconds":2617,"text":"same amount not calls the ping there's no rewards but in simulations the rewards are not working anyway","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2617s"},{"start_seconds":2625,"text":"so you need to manually do this we'll verify that that bob amount is still the same then pull resumes","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2625s"},{"start_seconds":2634,"text":"we verify that the pool has resumed the load to zero then we simulate that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2634s"},{"start_seconds":2641,"text":"the pool has acquired some rewards one and bob pinks the pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2641s"},{"start_seconds":2648,"text":"and we verify that the amount that bob received is positive that's very like simple","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2648s"},{"start_seconds":2656,"text":"simulation case which saying bob first deposited to the pool that verifies that the piles and resume","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2656s"},{"start_seconds":2664,"text":"works or simulates that it works and make sure that the pool doesn't stake during","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2664s"},{"start_seconds":2671,"text":"while being paused and then when resumed the pull actually stakes","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2671s"},{"start_seconds":2678,"text":"so this test verifies not only this but also that bob has acquired reward and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2678s"},{"start_seconds":2684,"text":"got distributed the reward um there's another test that verifies","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2684s"},{"start_seconds":2692,"text":"some logic but that's more complicated there are some unit tests on the bottom","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2692s"},{"start_seconds":2700,"text":"of this that's supposed to verify certain stuff so let's see what","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2700s"},{"start_seconds":2710,"text":"simple one it might be good enough that we just called them out as well that's fine we can take so","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2710s"},{"start_seconds":2719,"text":"some of these tests they are not ideal but they verify certain stuff that was good enough to make sure that mass adds","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2719s"},{"start_seconds":2726,"text":"up so internal pink is the method that you call or anyone can call actually like","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2726s"},{"start_seconds":2735,"text":"through pink to make sure rewards are distributed so right now we have active staking pools and there's a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2735s"},{"start_seconds":2744,"text":"contract or there's a account sponsored by one of uh near","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2744s"},{"start_seconds":2752,"text":"folks that basically pings every stake in pool like every 15 minutes","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2752s"},{"start_seconds":2760,"text":"to make sure they have distributed the rewards to display on the balance so the way rewards distribution","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2760s"},{"start_seconds":2767,"text":"works in the following we first check the current epoch height so if epoch height is the same","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2767s"},{"start_seconds":2775,"text":"then the epoch hasn't changed we return false so you don't need to restate but if epoch has changed then we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2775s"},{"start_seconds":2783,"text":"remember that the current epoch exists we get the new total balance of the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2783s"},{"start_seconds":2790,"text":"account um pink may be called when some tokens were deposited through deposit ballots","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2790s"},{"start_seconds":2798,"text":"and they already partnered there that pink is called before so we need to subtract this balance before we distribute","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2798s"},{"start_seconds":2806,"text":"the rewards so we get the total amount that the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2806s"},{"start_seconds":2813,"text":"account is has including both locked balance and unlocked balance so lock balance is a staked amount that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2813s"},{"start_seconds":2822,"text":"acquires rewards unlocked balance is the it also may have rewards in certain scenarios where you decrease","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2822s"},{"start_seconds":2830,"text":"your stake but your rewards will still be reflected for the next two epochs","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2830s"},{"start_seconds":2838,"text":"and they will come to them and state them out we verify this is the assert","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2838s"},{"start_seconds":2845,"text":"that the total balance is more than the previous total balance this invariant","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2845s"},{"start_seconds":2853,"text":"that the stake can pull is requires and there was a bunch of stuff on","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2853s"},{"start_seconds":2861,"text":"testnet that happened to fail this invariant because people still had access key on the same staking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2861s"},{"start_seconds":2868,"text":"tool and when you have it you spend the balance for gas and you may decrease your total balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2868s"},{"start_seconds":2875,"text":"without acquiring the reward","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2875s"},{"start_seconds":2883,"text":"finally we calculate the amount of reverse that the stake input received this is total balance minus the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2883s"},{"start_seconds":2890,"text":"previous known total balance so the balance from the previous epoch","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2890s"},{"start_seconds":2900,"text":"and if the rewards are positive we distribute them the first thing we do we calculate","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2900s"},{"start_seconds":2908,"text":"the reward that the owner takes for themselves as a commission","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2908s"},{"start_seconds":2915,"text":"so we multiply this fraction by the total reward received","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2915s"},{"start_seconds":2925,"text":"and this is fairly similar rounded down numerator in u256 multiplied by value divided by","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2925s"},{"start_seconds":2932,"text":"denominator and u256 so this is the amount in the octane year","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2932s"},{"start_seconds":2939,"text":"that the owner will keep for themselves and this is the remaining rewards we're","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2939s"},{"start_seconds":2946,"text":"saying all the remaining rewards have to be restaked","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2946s"},{"start_seconds":2952,"text":"and it goes here to be restaked","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2952s"},{"start_seconds":2964,"text":"then we calculate how many so so owner received the rewards in yocta near not in shares but","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2964s"},{"start_seconds":2973,"text":"because all the logic has to be in shares essentially the owner of the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2973s"},{"start_seconds":2981,"text":"purchases shares at the price of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2981s"},{"start_seconds":2991,"text":"at the price at which","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2991s"},{"start_seconds":2999,"text":"the post reward distributions to the rest of the delegators","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=2999s"},{"start_seconds":3007,"text":"and this is the number of share that owner will receive as a compensation for running the sticking pool if it's positive we increase the amount","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3007s"},{"start_seconds":3016,"text":"of shares and save the owner account back and we also increase the total amount of stake in shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3016s"},{"start_seconds":3023,"text":"if for some reason around and down this balance became zero so reward was very small and the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3023s"},{"start_seconds":3031,"text":"price per share was very large and only received zero rewards","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3031s"},{"start_seconds":3038,"text":"then um then this balance will just go to the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3038s"},{"start_seconds":3044,"text":"price per share instead of compensating the owner","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3044s"},{"start_seconds":3053,"text":"and finally we put some total login data saying the the current type of exists","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3053s"},{"start_seconds":3060,"text":"we received the rewards in that amount of staking shares or in tokens the now the total stake balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3060s"},{"start_seconds":3068,"text":"of the pool is this and number of shares this is the only way we expose the number of shares to external world is through the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3068s"},{"start_seconds":3077,"text":"logs is this and if uh owner received rewards is saying","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3077s"},{"start_seconds":3083,"text":"total reward he was so many shares and finally we just remember the new","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3083s"},{"start_seconds":3091,"text":"total balance and that's it so we distributed all rewards in a constant time we only","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3091s"},{"start_seconds":3101,"text":"updated one account and this is the owner's account for commission and only if the commission was positive","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3101s"},{"start_seconds":3114,"text":"so what else would be interesting here um the interesting part probably","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3114s"},{"start_seconds":3122,"text":"is something like a steak or a steak let's see for example a staking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3122s"},{"start_seconds":3129,"text":"thing so the wave is taken that is when we do price guarantee fund","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3129s"},{"start_seconds":3137,"text":"is let's say the predecessor in this case we're going to call it account id wants to take this amount of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3137s"},{"start_seconds":3145,"text":"tokens and balance is actually not a json type because it's internal methods we don't need json here","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3145s"},{"start_seconds":3153,"text":"we calculate how many shares around it down again down not up required","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3153s"},{"start_seconds":3161,"text":"to use take the given amount so this is how many shares the owner owner will receive it has to be positive","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3161s"},{"start_seconds":3169,"text":"then we check the amount how much the owner should pay for the shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3169s"},{"start_seconds":3178,"text":"again round it down this is to guarantee that the owner when they purchased shares and converted back","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3178s"},{"start_seconds":3185,"text":"without rewards never lost the one yoktan year because it might break the current team finally the same","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3185s"},{"start_seconds":3195,"text":"that the account has enough amount to pay","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3195s"},{"start_seconds":3202,"text":"for the amount charged and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3202s"},{"start_seconds":3209,"text":"we give the unstaked we decrease the internal and state balance increase the internal","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3209s"},{"start_seconds":3217,"text":"number of shares balance of the account and the stake amount we round this up so the number of shares","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3217s"},{"start_seconds":3226,"text":"actually rounded up so this one extra penny or like one extra yak 10 year will come from the guaranteed fund","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3226s"},{"start_seconds":3234,"text":"during the rounding of the shares up so we charge user less but we contributed to the amount","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3234s"},{"start_seconds":3244,"text":"more from this one trillion yaktas that we had originally designated for this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3244s"},{"start_seconds":3251,"text":"and this uh difference usually is just one yoctaner that may come from rounded up or down","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3251s"},{"start_seconds":3263,"text":"and this is the amount of total stake balance and number of shares increasingly minted new shares finally we","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3263s"},{"start_seconds":3271,"text":"put a log and return and unstaking works very similarly you round up","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3271s"},{"start_seconds":3280,"text":"to this amount of shares you need to pay we calculate how much amount you receive again rounding up","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3280s"},{"start_seconds":3286,"text":"to be overpaying you for this but this also comes from guaranty fund","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3286s"},{"start_seconds":3295,"text":"and we decrease the shares to increase the amount and saying when you can unlock","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3295s"},{"start_seconds":3302,"text":"between four epochs and this is downstate amount to the rounded it down so we understand slightly less to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3302s"},{"start_seconds":3310,"text":"guarantee the price of other participants of the pool so that's pretty much how the staking","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3310s"},{"start_seconds":3318,"text":"pool works and how mass works we compensate for rounding errors from","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3318s"},{"start_seconds":3328,"text":"from the font that we allocated","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3328s"},{"start_seconds":3338,"text":"okay i think um the amount of time that we wanted to spend on this and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3338s"},{"start_seconds":3346,"text":"we can do a few questions and then finish it up let me know if you have i've got a pile of questions but i've been talking a lot so i'll wait a few seconds to see if","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3346s"},{"start_seconds":3355,"text":"anybody else wants to ask okay yeah okay go ahead","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3355s"},{"start_seconds":3365,"text":"okay i'll just fire off the questions then you can decide what you want to answer okay um just an in order of of how these occurred to me","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3365s"},{"start_seconds":3373,"text":"uh while you were talking um so uh you mentioned ristretto keys are required for validators or validator","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3373s"},{"start_seconds":3381,"text":"nodes i was wondering why that is it seems like there's some kind of subset of uh the curve keys that are somehow more secure based on what i checked out briefly i'm","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3381s"},{"start_seconds":3389,"text":"not quite sure if you can add to that does this stake share price guarantee fund set an upper limit on the lifetime of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3389s"},{"start_seconds":3397,"text":"the contract or does that get like refilled over time those are like the two maybe technical questions and then two questions around like a level of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3397s"},{"start_seconds":3405,"text":"effort and experience review like a retrospective on this work like level of effort like how long did this take to design and build","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3405s"},{"start_seconds":3413,"text":"how many people were involved how many revisions were there and then for experience like what was the hardest part of this for you what was the most surprising any discoveries that you made any","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3413s"},{"start_seconds":3422,"text":"changes that were put into the protocol like during the development of this because of its development that kind of stuff","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3422s"},{"start_seconds":3429,"text":"all right so so for strata it's pretty much yes so we updated it during the design of this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3429s"},{"start_seconds":3436,"text":"um contract and that was a surprise that we needed to account for this um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3436s"},{"start_seconds":3444,"text":"then second was about the price guarantee so one trillion should be enough for like half","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3444s"},{"start_seconds":3451,"text":"like 500 billion transactions so that should be long enough for the staking pool","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3451s"},{"start_seconds":3458,"text":"so it cannot be refilled because the rewards will be immediately redistributed to the total stake balance","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3458s"},{"start_seconds":3466,"text":"on the next ping um so it's a lifetime of the contract i say","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3466s"},{"start_seconds":3474,"text":"but it's unlikely to happen um next was the question about the level of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3474s"},{"start_seconds":3482,"text":"expertise i think we spent on this contract quite a bit because and we did tons of security","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3482s"},{"start_seconds":3490,"text":"reviews including like internally and externally especially around this mass that was","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3490s"},{"start_seconds":3498,"text":"complicated some stuff was discovered like this or strata key popped up","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3498s"},{"start_seconds":3504,"text":"during the reviews so we marked the change lock of this contract as well","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3504s"},{"start_seconds":3511,"text":"in the readme there there's a bunch of stuff","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3511s"},{"start_seconds":3519,"text":"that popped up during the development and testing on the live system but the original version was um","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3519s"},{"start_seconds":3528,"text":"it took maybe like a week to write and later like clean it up test it properly","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3528s"},{"start_seconds":3536,"text":"and improve and then we did a bunch of revisions","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3536s"},{"start_seconds":3543,"text":"so pausing and resuming was asked by the pool because otherwise the owner had no ability to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3543s"},{"start_seconds":3551,"text":"unstake and if their node goes down they will be attacking the network essentially this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3551s"},{"start_seconds":3558,"text":"active stake kind of requesting the validation and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3558s"},{"start_seconds":3566,"text":"not running the network so right now we don't have slashing so this was just not an issue for the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3566s"},{"start_seconds":3575,"text":"participants but it will it was an issue for the network itself so that way the owner can pause the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3575s"},{"start_seconds":3584,"text":"staking and just if they don't want to run the pool they migrate into the pool and communicate as much as possible before this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3584s"},{"start_seconds":3592,"text":"next we updated the vote interface to match the final phase two voting contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3592s"},{"start_seconds":3598,"text":"those helper view methods and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3598s"},{"start_seconds":3605,"text":"to be able to query accounts in a human readable way and finally there was some improvements around batching methods together","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3605s"},{"start_seconds":3614,"text":"so deposit mistakes they call and stay call withdrawal instead of like you have to make a view call first get them uh","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3614s"},{"start_seconds":3622,"text":"put them out to call the stake and the way we fixed it i think you can spend a few minutes on this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3622s"},{"start_seconds":3631,"text":"when you stake not only you take the amount we also attach a promise to check if the stake was successful","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3631s"},{"start_seconds":3639,"text":"it needed for two things so you if you're trying to stick with invalid key not restricted","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3639s"},{"start_seconds":3647,"text":"specific key then the promise before execution will fail so it will fail validation","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3647s"},{"start_seconds":3655,"text":"before sending it and that will make it uh so this way you don't need to check it within the contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3655s"},{"start_seconds":3663,"text":"it will revert the last call and it's all gonna be good but we also introduced the minimal seat","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3663s"},{"start_seconds":3671,"text":"on the contract and the minimum not not minimum minimum stake on the protocol level","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3671s"},{"start_seconds":3679,"text":"so minimum stake is one tenth of the amount of last seed price","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3679s"},{"start_seconds":3687,"text":"and if your contract tries to stake less than this then the action will fail and you will","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3687s"},{"start_seconds":3694,"text":"not send the prop so let's say you want to unstake some amount and you dropped your balance below","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3694s"},{"start_seconds":3704,"text":"one tenth of the stake so the stake in action may fail and you will not understate while you","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3704s"},{"start_seconds":3712,"text":"need it to guarantee that on stake infested it has to happen in this case we have this callback on that checks that the stake in action","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3712s"},{"start_seconds":3721,"text":"has successfully completed and this callback it basically","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3721s"},{"start_seconds":3730,"text":"checks that if it fails","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3730s"},{"start_seconds":3738,"text":"if it fails and the balance is positive we need to unstake so it will call and stake an","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3738s"},{"start_seconds":3746,"text":"action where the stake amount to zero to make sure that the all balance is released and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3746s"},{"start_seconds":3753,"text":"you can withdrawing for epochs and just standings during the testing of these contracts","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3753s"},{"start_seconds":3760,"text":"that we did on the beta 9 test notes before maintenance so it took like uh the contract was","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3760s"},{"start_seconds":3769,"text":"ready maybe around the summer time so the testing of this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3769s"},{"start_seconds":3777,"text":"iteration of this took probably like two three four months due to complexity that it involves uh","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3777s"},{"start_seconds":3786,"text":"interacting with the protocol and as for learning so quite a lot of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3786s"},{"start_seconds":3794,"text":"learning so from pagination to helper methods and batching together some stuff so one thing that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3794s"},{"start_seconds":3802,"text":"would be really nice to have is take or like deposit and stake all on a lock-up contract","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3802s"},{"start_seconds":3809,"text":"so right now lockup you have to issue manually how much you want to stake on a","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3809s"},{"start_seconds":3818,"text":"local contract but it would be great that you didn't need to think about your year how much it's locked for storage and stuff like","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3818s"},{"start_seconds":3825,"text":"this and just you want to stake everything from your locker but because it was already deployed it was too late to think about this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3825s"},{"start_seconds":3836,"text":"there's also some gas that is hardcoded and this the common decrease in fee","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3836s"},{"start_seconds":3844,"text":"this this numbers cannot be changed because they're already on chain the world is not important but this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3844s"},{"start_seconds":3854,"text":"method requires you to have a large number for every stake actually and you cannot decrease it","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3854s"},{"start_seconds":3862,"text":"so every like risk taking action on every call on this contract will require us to have","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3862s"},{"start_seconds":3868,"text":"a large amount of gas and the problem is that that's wasteful it's wasteful uh we had a proposal to","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3868s"},{"start_seconds":3877,"text":"burn all the gas that you attach and in this case once the heat goes down and we decide let's say we agree on burning all the gas","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3877s"},{"start_seconds":3885,"text":"this gas will be always burned like wasted plus it like limits the number of","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3885s"},{"start_seconds":3893,"text":"transactions you can put into one block because of the that gas amount if we are restricting based on this case","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3893s"},{"start_seconds":3902,"text":"finally there was like lots of iteration on the testing of the contract using the simulation test framework that","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3902s"},{"start_seconds":3909,"text":"we improved a lot and from this learning if we get to the","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3909s"},{"start_seconds":3917,"text":"lock-up contracts eventually you can see how the structure of local contracts improved over this one","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3917s"},{"start_seconds":3925,"text":"and like there's a better structure on this forces so like we split all the methods there's getters internal","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3925s"},{"start_seconds":3933,"text":"owners method foundation methods types utilities so this is still bundled together but it was a good","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3933s"},{"start_seconds":3940,"text":"iteration and credibility of the contracts plus a lot of stuff was improved on near","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3940s"},{"start_seconds":3949,"text":"sdk itself um on nearby gym to to help support some stuff like this","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3949s"},{"start_seconds":3958,"text":"public key serialization for example so you don't need to think about how the json string converts into","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3958s"},{"start_seconds":3965,"text":"inner 32 bytes representation","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3965s"},{"start_seconds":3976,"text":"yeah so that's like a review i think that was more technical than the first one and","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3976s"},{"start_seconds":3983,"text":"let us know if you have any feedback and we'll try to improve on it thank you","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3983s"},{"start_seconds":3994,"text":"any final comments before this step","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=3994s"},{"start_seconds":4005,"text":"no okay thanks everyone","url":"https://www.youtube.com/watch?v=ny6_YIlkxYM&t=4005s"}],"youtube_url":"https://youtube.com/watch?v=ny6_YIlkxYM","url":"https://near-pedia.xyz/videos/ny6_YIlkxYM"}