OriginProtocol / ousd-governance

OUSD Governance Portal and Contracts
11 stars 4 forks source link

Enable fee distribution to OGV stakers #297

Closed zack-eth closed 2 years ago

zack-eth commented 2 years ago

Please see https://github.com/OriginProtocol/origin-dollar/pull/1058 (this feature requires changes in both repositories)

franckc commented 2 years ago

Thanks for making this change! Can we add a unit test to make sure this works as expected?

DanielVF commented 2 years ago

@shahthepro I think the "calcRewards()" internal method name may be a little confusing here, perhaps it should be changed to "calculateInflation()" and then the rest of code can get much clearer.

The actual rewards payout is then two independent if's. If we have balance, we pay that. If we have inflation, then we we mint the inflation. We don't need to do two balance checks, once to add in _calcRewards and once to subtract in collectRewards.

shahthepro commented 2 years ago

I think the "calcRewards()" internal method name may be a little confusing here, perhaps it should be changed to "calculateInflation()" and then the rest of code can get much clearer.

The actual rewards payout is then two independent if's. If we have balance, we pay that. If we have inflation, then we we mint the inflation. We don't need to do two balance checks, once to add in _calcRewards and once to subtract in collectRewards.

@DanielVF Have changed the method name _calculateInflation() and have also removed the balance check from this method. However, I had to add the balance check to previewRewards() method, which seems to be used by other contracts (OgvStaking.sol) and the DApp

DanielVF commented 2 years ago

We'll need to make sure slither checks pass before merging to master. In this case is concerned that we are ignoring the final amount from the swap. We don't actually need it, since the check on min size is handled by the swap, so we can safely ignore it.

I think the right comment is something like // slither-disable-next-line slither-disable-next-line

shahthepro commented 2 years ago

I think the right comment is something like // slither-disable-next-line slither-disable-next-line

Yep, // slither-disable-next-line unused-return works

DanielVF commented 2 years ago

We'll need a deploy test for this PR.

Would also be good to paste the fork tests into the issue so others can play with them.

shahthepro commented 2 years ago

Have added the deploy script. Copying my own message from Discord:

Also, here's the script I used to test the deployment on fork

import os
from brownie import *

def main():
    deployer = accounts.add(os.environ["DEPLOYER_KEY"])
    FROM = {'from': deployer}
    OGV_PROXY_ADDRESS = "0x9c354503c38481a7a7a51629142963f98ecc12d0"
    rewards = run("deploy_002_upgrade_rewards_source")

    ogv = OriginDollarGovernance.at(OGV_PROXY_ADDRESS)
    governor = accounts.at(rewards.governor(), force=True)

    # Allow deployer to mint
    ogv.grantMinterRole(deployer.address,{'from':governor})

    # Fetch current balance and rewards
    (curr_balance, curr_rewards) = fetch_balance(ogv, rewards)

    # Send some OGV to the new contract
    print("Minting 10k OGV to contract")
    ogv_to_mint = 1e4 * 1e18
    ogv.mint(rewards.address, ogv_to_mint, FROM)

    # Fetch new balance
    (new_balance, new_rewards) = fetch_balance(ogv, rewards)

    # Check if any balance added to the contract 
    # is being calculated in the rewards
    print("Expected Balance:", curr_balance + ogv_to_mint)
    print("Actual Balance:  ", new_balance)

    print("Expected Rewards:", curr_rewards + ogv_to_mint)
    print("Actual Rewards:  ", new_rewards)

def fetch_balance(ogv, rewards):
    curr_balance = ogv.balanceOf(rewards.address)
    curr_rewards = rewards.previewRewards()

    print("Current Balance:", curr_balance)
    print("Current Rewards:", curr_rewards)

    return (curr_balance, curr_rewards)
DanielVF commented 2 years ago

I'll have to give this a full review another day, but it's looking good so far. Thanks!

DanielVF commented 2 years ago

Requirements

This PR handles inserting OGV bought back back from users into the existing rewards distribution process. Any OGV sent to the rewards contract is passed on to the staking contract as addtional rewards on top of inflation.

Invariants

Internal State

See Invariants section above

Skiping reviewing other contract state, which is not changed by this PR.

Attack

If there was some way to increase the amount minted, that would be bad. But this code makes no changes to those calculations.

Logic

Good

Tests

Deployment Considerations

None

Flavor

Code is simple.

Crashes in collectRewards do not affect staking contract. Crashes in previewRewards would affect previewing in staking contract, but nothing else.

Overflow

Black magic

No magic

Dependencies

Deploy

Deploy process transfers ownership of the implimentation contract to current governance. This is probably unnessasay, but won't hurt.

Authentication

No changes to authentication

Cryptographic code

No crypto

Gas problems

No for loops

External calls

Only addtional external calls are to balanceOf() and transfer() on OGV.

Ethereum

DanielVF commented 2 years ago

Correct, solidity >= 0.8 means no safe math needed.