Content pfp
Content

@

https://warpcast.com/~/channel/vyper
0 reply
0 recast
0 reaction

Vitalik Buterin pfp
Vitalik Buterin

@vitalik.eth

The contract here is a sublinear staking contract: if you are in the whitelist (specified as an ERC1155 collection), then you can stake N coins, and get a return of N ** 0.75 coins per slot, for as long as the contract has coins to pay for it. There is a fundedUntil mechanism that ensures that if the contract runs out of money, every staker gets rewarded for every slot up to the fundedUntil timestamp, and the mechanism doesn't turn into a fractional reserve. https://github.com/ethereum/research/blob/master/sublinear_staking/code.vy Bounty of total 2 ETH for identifying any bugs / vulnerabilities in the contract and proposing specific fixes, if multiple issues are found the bounty will be split based on severity. Amount: 2 ETH @bountybot
19 replies
68 recasts
340 reactions

androolloyd.hl pfp
androolloyd.hl

@androolloyd

something worth noting the isEligible check only happens on staking, so a user can acquire inline a token to flag true without having to actually hold the token for the duration of the staking. You'd likely want to do something where the eligible tokenID is locked into the staking contract for the duration.
1 reply
0 recast
0 reaction

✳️ dcposch pfp
✳️ dcposch

@dcposch.eth

not a vulnerability, but you probably want a configurable multiplier on getReturnPerSlot, otherwise results depend on token decimals. for example, stake 1 USDC = 1e6 ^ (3/4) = $0.03 reward per slot stake 1 DAI = 1e18 ^ (3/4) = $0.00003 reward per slot
0 reply
0 recast
9 reactions

Francesco Piccoli pfp
Francesco Piccoli

@francescop

Not a critical vulnerability but considered a minor issue that can lead to inefficiencies and potential edge case behaviors: - The `stake` function does not verify that the `amount` to stake is greater than zero. Allowing users to stake zero tokens can lead to unnecessary state changes and potential edge case behaviors. - Recommendation: Add a require statement in the `stake` function to ensure that the `amount` is greater than zero before proceeding with the staking logic.
1 reply
0 recast
4 reactions

Varun Srinivasan pfp
Varun Srinivasan

@v

Cc @linda
0 reply
0 recast
1 reaction

horsefacts pfp
horsefacts

@horsefacts.eth

hey @z80.eth
0 reply
0 recast
2 reactions

Dennison Bertram pfp
Dennison Bertram

@dennison

This is pretty incredible to see! Have you seen our Governance Staking Contracts? To use staking to drive participation in governance? https://github.com/withtally/govstaking
0 reply
0 recast
0 reaction

Francesco Piccoli pfp
Francesco Piccoli

@francescop

Nice, we’ll run some scans with @almanax
0 reply
0 recast
0 reaction

🦒 pfp
🦒

@srijan.eth

cc @vhawk19
0 reply
0 recast
0 reaction

Catch0x22 pfp
Catch0x22

@catch0x22.eth

@askgina.eth can you explain what this contract is for in simple terms
0 reply
0 recast
1 reaction

vincemanguy pfp
vincemanguy

@vincemanguy

This is the way🤝
0 reply
0 recast
0 reaction

zkfriendly pfp
zkfriendly

@zkfriendly.eth

a1 stakes 1 eth at time 0. fast forward 1000 blocks. a2 stakes 0.1 eth. fundedUntil breaks
0 reply
0 recast
0 reaction

zkleo.eth pfp
zkleo.eth

@leoyanzon

I don't get this.. I mean, what is the purpose of this sublinear staking contract? A social experiment or smthing?
0 reply
0 recast
0 reaction

sarvad.base.eth pfp
sarvad.base.eth

@serverconnectd

ive never relly looked into to vyper but in the _unstake function shouldnt there be a require like check if the total amount to be sent back to the user is available in the contract?
0 reply
0 recast
0 reaction

Xloya pfp
Xloya

@chlo11e

Nice
0 reply
0 recast
0 reaction

sebayaki.eth pfp
sebayaki.eth

@if

looks good overall, but I found a few potential issues: 1. ```vy def _fundedUntil() -> uint256: return ( self.liabilitiesLastUpdated + (staticcall STAKED_TOKEN_ADDRESS.balanceOf(self) - self.liabilities) // max(self.totalPayoutPerSlot, 1) ``` If the contract’s balance of the staked token `balanceOf(self)` is less than the total liabilities `self.liabilities`, the subtraction will underflow, causing a revert on `_unstake` method. It might be okay, but it would be better to handle it properly. 2. ```vy def stake(amount: uint256): ``` A user can stake an amount of 0, which could cause potential issues in other parts. I think adding an assertion `assert amount > 0` if staking a zero amount is not intended.
0 reply
0 recast
0 reaction

Fractal Visions pfp
Fractal Visions

@fractalvisions.eth

🤔
0 reply
0 recast
0 reaction

Codingsh pfp
Codingsh

@codingsh

I'm in
1 reply
0 recast
0 reaction

ruz pfp
ruz

@ruz

Ser. Can you make the contract hold an LP position, and pay out the LP yield? In this way, you have a lower initial payout but it could continue indefinitely.
0 reply
0 recast
0 reaction

CryptoProfeta  pfp
CryptoProfeta

@cryptoprofeta

Potential Bugs and Vulnerabilities in the Sublinear Staking Contract Reentrancy in _unstake: The _unstake function includes a transfer of tokens (extcall STAKED_TOKEN_ADDRESS.transfer). If the ERC20 token's transfer method is reentrant (e.g., custom implementation or callback mechanism), this could cause issues. Mitigation: Use a reentrancy guard or adjust state variables before the transfer. Rounding Errors in Rewards Calculation: The getReturnPerSlot function relies on integer square roots. Rounding could lead to incorrect reward calculations for small or large stakes. Test cases for edge conditions should verify correct behavior. Incorrect Liabilities Adjustment: In _unstake, liabilities are adjusted as self.liabilities -= totalOut. If there are multiple simultaneous unstake operations, there's a risk of inconsistent state updates due to race conditions. Mitigation: Implement locks or atomic operations to manage state updates. Division by Zero in _fundedUntil:
0 reply
0 recast
0 reaction