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% ```