Treasury Farm Proposal
> This is for FA1.2 contracts only
## Approve functionality
Technical challenge: Farm A can't fetch current allowance from FA1.2. Current allowance is used as `expected` parameter when updating the allowance (increase or decrease).
```
type approveCASParameter =
[@layout:comb]
{
expected: nat,
spender: address,
value: nat,
};
```
Solution is an internal ledger that keeps track of this value.
## Flow for automatic claim()
> recommended
Every user claim() on Farm A triggers a claim() on Farm B. Farm A keeps track of two accumulatedRewardPerShare internally. However, updatePool does not work on a per block basis, but updates the incoming reward by checking its increased balance (getBalance() call on FA).
```sequence
User -> FA: approve(Farm A)
User -> Farm A: deposit()
Farm A -> FA: transfer()
Farm A -> FA: approve(Farm B)
Farm A -> Farm B: deposit()
Farm B -> FA: transfer()
note over User: time passes
User -> Farm A: claim()
Farm A -> FA Reward A: transfer()
Farm A -> Farm B: claim()
Farm B -> FA Reward B: transfer()
note over Farm A, Farm B: DFE execution
Farm A -> FA Reward B: getBalance(Farm A)
FA Reward B -> Farm A: updatePoolExternal()
note over Farm A: updatePoolFARewardB \n (parallel farm within farm)
Farm A -> FA Reward B: transfer(Farm A, User, reward)
Farm A -> FA Reward B: transfer(Farm A, Beneficiary, fraction reward)
```
Additions to storage
```
accumulatedRewardBPerShareStart for every user
global state accumulatedRewardBPerShare
stakedBalanceToFarmB: nat
feeOnRewardB: nat
beneficiary: address
farmB: address
FA_B: address
```
New Entrypoint
```
callback for getBalance to finalize updatePoolExternal()
```
Internal Functions
* a farm "within" the farm, to be triggered with updatePoolExternal()
* governable `fee` on Farm B reward token to be sent to a benefeciary address (DAO's treasury)
Considerations
* claim of farm B gets triggered automatically on deposit() and withdraw(), but not on claim() (to save gas costs?, dust transactions...)
* claim of farm B can be triggered by anyone manually
## Flow for by admin claim()
> not recommended
```sequence
User -> FA: approve(Farm A)
User -> Farm A: deposit()
Farm A -> FA: transfer()
Farm A -> FA: approve(Farm B)
Farm A -> Farm B: deposit()
Farm B -> FA: transfer()
note over User: time passes
User -> Farm A: claim()
Farm A -> FA Reward A: transfer()
note over User: more time passes
Admin -> Farm A: claim()
Farm A -> Farm B: claim()
Admin -> Farm A: transferClaim()
note over Admin: Admin claimed 100%
```