Technical Details
How farms work inside the swap.alcor contract.
Farms are part of the swap.alcor contract. Rewards are calculated on-chain, without a backend.
Tables
incentives: one row per farm: creator, pool, reward token and amount, duration, end time, reward rate, total staking weight and number of stakes.stakingpos: for each staked position, the list of farms it is staked in.stakes: scoped by farm ID; one row per staked position, with its staking weight and rewards earned.incentivefee: the farm creation fee for accounts that are not token issuers.
Actions
| Action | What it does |
|---|---|
newincentive | Creates a farm for a pool. |
stake(incentiveId, posId) | Stakes a position in a farm. |
stakelastpos(incentiveId) | Stakes the newest position of the farm's pool; used to open and stake a position in one transaction. |
getreward(incentiveId, posId) | Pays out the rewards earned so far. |
unstake(incentiveId, posId) | Unstakes the position and pays out its rewards. |
Rewards are paid from the reward.alcor account, which holds the farms' reward tokens.
Reward calculation
The calculation follows the Synthetix staking-rewards model:
- Reward rate = reward amount / duration, paid per second until the end time.
- Staking weight of a position = √(amount A × amount B), from the token amounts the position holds when it is staked. It is recalculated when liquidity is added to or removed from the position. An out-of-range position holds one token only, has zero weight and cannot be staked.
- Each staked position earns the reward rate × its weight / the total weight of the farm, for every second it is staked.
- When the creator adds rewards, the new amount plus the undistributed remainder is spread over a new full duration from that moment.
- A position can be staked in at most 15 farms at once.