airswap / airswap-aips

AirSwap Improvement Proposals
22 stars 3 forks source link

AIP 18: Conversion of rewards to sAST for Compounded Staking #18

Open agriimony opened 3 years ago

agriimony commented 3 years ago

Summary

To incentivize long term holding of AST, we should encourage re-investment of staking rewards back into staked tokens. This proposal aims to provide stakers with a convenient user interface for converting fee rewards back into staked AST tokens.

Specification

A new function will be introduce on the pool contract which will perform a swap between the token and AST, and send it to the locker contract on behalf of the claimant's wallet.

In terms of user interface, it can be a simple <compounded stake mode> toggle button which can be toggled on or off during the claiming phase. When toggled on, the claiming interface should show the amount of AST which could be potentially claimed based on the fee reward and the current AST price.

Updated stake function

AIP17 introduced a new staking contract where each new stake would require it's own timestamp. This means that unstaking of multiple small stakes (which would happen in AIP18) starts to become impractical in terms of gas fees. To combat this, auto-compounding on AIP18 would extend the last existing stake based on the fraction of the new stake to the existing staked amount. If the last stake has already finished it's vesting period (i.e. 100% available to unstake), then the new stake will form a new pool.

IF (CURRENT - TIMESTAMP) < MAX_VESTING_TIME; TIMESTAMP = TIMESTAMP + (CURRENT - TIMESTAMP) * NEWSTAKE/(NEWSTAKE + OLDSTAKE) #updates timestamp STAKE = NEWSTAKE + OLDSTAKE #updates staked amount ELSE; CREATE_NEW_STAKE()

This means that rapidly incoming small stakes will simply shift the starting time of the existing stake slightly rather than form a new stake pool. Any vesting period remains the same as defined by the locker contract, albeit shifted by a certain time frame.

Example

We will use the parameters from AIP17 in this example (i.e. 4 weeks cliff, 5% unlocked per week, with 100% unlocked at week 20)

Adam has 100,000 AST staked on week 0. He uses his stake to vote on an AIP which he receives 100,000 points. At week 4, he uses his 100,000 points to claim 9.09% of a USDC pool worth 5,000 USDC. His reward is 454.54 USDC and he wishes to convert this reward into staked AST.

By using the auto-compounding function, the smart contract swaps 454.54 USDC into 2272 AST (at a rate of 0.2 USDC/AST from the market) using a Dex aggregator. The 2272 AST is deposited into the locker contract on behalf of his wallet.

CURRENT = 2419200 #This is the current time (4 weeks in seconds) TIMESTAMP = 0 #Original time of stake at time 0

CURRENT-TIMESTAMP = 2419200 < 12096000 #the last stake is still active TIMESTAMP = 0 + (2419200 - 0) * 2272/(2272 + 100000) = 53743 #New time stamp is moved forward to 53743
STAKE = 2272 + 100000 = 102272

The vesting period is extended by 0.62 days due to the re-staking event. His new staked amount for that pool is updated to 102,272.

Rationale

Possible Benefits AST holders benefit as this would increase the buy pressure on AST (locking it up according to the staking rules)

The staker would benefit by allowing compounding of the fee rewards while paying less gas for the transactions (manually would require claim + transfer + swap + stake, auto-compounding should just be claim + swap + stake).

Possible Drawbacks Potentially, this might allow traders to game the system since it would be known that there might be a large wave of buy orders at the end of an AIP voting period. Traders might try to buy up AST just before voting ends to drive up the price before dumping it again.

This problem is solved by AIP21 or AIP22 which smoothens the claiming process. This removes the claim load at specific times (e.g. at the end of a vote)

Credits

Thanks to VladislavW and 2x for help with the AIP

Copyright — All proposals are public domain via CC0.

agriimony commented 2 years ago

Updates to the staking contract - using extend to add to current stakes. This would allow all stakes from a single wallet to be consolidated into one event, saving gas fees when calling balanceOf.

A few considerations

  1. the user should maintain the available balance to unstake
  2. 39 relies on stakeTime to calculate point emission, would need an alternative if consolidating to a single staking event

Naive implementation The naive implementation should calculate the current available balance to unstake and back calculate the initial stake time required to achieve the same available balance at the time when extend is called. This means that we will not be able to implement the cliff function.

available = ( now() - stakeTime ) / vestingLength * totalStake // calculate amount available to unstake totalStake = totalStake + newStake // Update totalStake to include new staked amount vestingLength = newVestingLength // Update vestingLength stakeTime = now() - available * vestingLength / totalStake // Back calculate what stakeTime should be to achieve same available

Instead of rewarding additional points for longer stakeTime according to #39, we could change the contract to allow stakers to pre-determine their lock-in period based on the vestingLength. Each extend call will need to provide amount of AST staked as well as a new vestingLength. If not provided, the contract should assume that vestingLength remains unchanged.

vestingLength should only be allowed to be extended and not reduced. This will prevent stakers from early unstaking by simply calling extend

Points payout via activate should award higher % of points for addresses with longer vestingLengths

e.g.

agriimony commented 2 years ago

also, extendFor should not be allowed to change vestingLength. This will prevent attacking of a person's wallet by allowing a different person to extend the vestingLength of his current stake

agriimony commented 2 years ago

agrimony Feb 16

I guess if the price of AST is deemed to be too high at that point in time, the claimant can always choose not to convert rewards into sAST, or to do so at a later time. This might be dependent on how fee-rewards are going to be handled in the future.


VladislavW Feb 16

The staker would benefit by allowing compounding of the fee rewards without needing to pay for the gas fees involved with doing so manually (i.e. claiming the tokens, converting to AST and sending the AST to the staking contract).

That would be done anyway and usually the manual process is much cheaper if you know what to do. So the transaction cost would be around 100$ or higher according to the gas price 100+ gwei. But it is good marketing move that will make people to stake more AST and support the price.

Possible Drawbacks
Potentially, this might allow traders to game the system since it would be known that there might be a large wave of buy orders at the end of an AIP voting period. Traders might try to buy up AST just before voting ends to drive up the price before dumping it again. Ideas about how we could protect against such an attack would be welcome.

I was thinking of this and i don’t see the big problem. Everyone will know the date of claiming so pumps will be balanced with sells. Also this is an option so not everyone will use it.

Also i see that you used my idea so i would be thankful if you share some AST AIP reward with me after the voting :smiley: https://discord.com/channels/590643190281928738/600678035657850890/810502360262639616 6


agrimony Feb 16

That would be done anyway and usually the manual process is much cheaper if you know what to do. So the transaction cost would be around 100$ or higher according to the gas price 100+ gwei.

Yeah I’m not sure how the gas will be dealt with in this case, but had assumed that a smart contract might do it more cheaply. Wonder if some of the gas fees can be offsetted by the rewards pool as well in this case to incentivize this mode of rewards payout.

Also i see that you used my idea so i would be thankful if you share some AST AIP reward with me after the voting

Thanks, added a contributors section as well who will all share in the AIP reward.

The idea was brought up a few times by various members of the community so I don’t think it really belongs to any one person (e.g. here’s me raising the idea as well a few days before: Discord). I can’t remember who else joined in the discussions, but if I left out any names please let me know! Happy to share the rewards with all :slight_smile:


2xAST Feb 18

Possible Drawbacks
Potentially, this might allow traders to game the system since it would be known that there might be a large wave of buy orders at the end of an AIP voting period. Traders might try to buy up AST just before voting ends to drive up the price before dumping it again. Ideas about how we could protect against such an attack would be welcome.

This could be offset by using treasury AST. The treasury would sell AST to stakers at the current market price. Then place limit-orders on the market to buy back the sold AST. These orders could be placed at a lower price, creating support. If they get filled it would even turn a profit.

There could also be a time limit on the orders, if they don’t get filled for example within two years, the funds can be used to fund development etc. Treasury would probably need to sell AST for development either way, so this could be a convenient way to do it.


13 days later VladislavW Mar 3

Possible Drawbacks
Potentially, this might allow traders to game the system since it would be known that there might be a large wave of buy orders at the end of an AIP voting period. Traders might try to buy up AST just before voting ends to drive up the price before dumping it again.

That wouldn’t be a problem after points vesting system implementation.

agriimony commented 2 years ago

Points payout via activate should award higher % of points for addresses with longer vestingLengths

e.g.

  • 12 weeks: 75%
  • 20 weeks: 100% (current implementation)
  • 30 weeks: 110%
  • 52 weeks: 120%
  • 78 weeks: 125%
  • 104 weeks: 130%

There is a potential attack vector introduced in this way. An attacker would stake maximum AST upfront for a short period of vestingLengthbefore calling extendusing 0 (or minimal) AST and a long period of vestingLength. This enables the attacker to maximize claim points while still being able to fully unstake at any time (assuming that he is not going to stake more tokens in the future)

Potential solution would be to disallow extendfrom updating vestingLength. (i.e. the vestingLength committed to at the start CANNOT be changed until fully unstaked and starting a new stake)