Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rebrand OGV contracts and tweak Governance parameters #406

Merged
merged 8 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from brownie import *
import brownie

BLOCKS_PER_DAY = 86400 / 12 # 12 blocks per second

STRATEGIST = '0xF14BBdf064E3F67f51cd9BD646aE3716aD938FDC'
GOV_MULTISIG = '0xbe2AB3d3d8F6a32b96414ebbd865dBD276d3d899'
GOVERNOR_FIVE = '0x3cdd07c16614059e66344a7b579dab4f9516c0b6'
Expand All @@ -28,11 +30,12 @@ def governanceProposal(deployment):
return

actions = deploymentInfo['actions']
print('Executing governance proposal')

if (len(actions) > 0):
ogvGovernor = Contract.from_explorer(GOVERNOR_FIVE)
with TemporaryFork():

print('Creating governance proposal on fork')
propose_tx = ogvGovernor.propose(
[action['contract'].address for action in actions],
[0 for action in actions],
Expand All @@ -45,7 +48,32 @@ def governanceProposal(deployment):
deploymentInfo['name'],
{'from': GOV_MULTISIG}
)
proposalId = propose_tx.events['ProposalCreated'][0][0]['proposalId']

# Move forward 30s so that we can vote
timetravel(30)

# Vote on Proposal
print("Voting on the proposal")
ogvGovernor.castVote(proposalId, 1, {'from': GOV_MULTISIG})

# 3 days to queue (+2 for buffer since contract has a different BLOCKS_PER_DAY now)
timetravel(86400 * 5)

print("Queueing proposal")
ogvGovernor.queue(proposalId, {'from': GOV_MULTISIG})

# 2 day timelock (+1 day for buffer)
timetravel(86400 * 3)

print("Executing proposal")
ogvGovernor.execute(proposalId, {'from': GOV_MULTISIG})


print("Execute the following transaction to create OGV Governance proposal")
print("To: {}".format(propose_tx.receiver))
print("Data: {}".format(propose_tx.input))

def timetravel(seconds):
sparrowDom marked this conversation as resolved.
Show resolved Hide resolved
brownie.chain.sleep(seconds + 1)
brownie.chain.mine(int(seconds / BLOCKS_PER_DAY) + 1)
4 changes: 4 additions & 0 deletions contracts/GovernanceToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ contract OriginDollarGovernance is
override
onlyOwner
{}

function name() public view virtual override returns (string memory) {
return "Origin DeFi Governance";
}
}
2 changes: 1 addition & 1 deletion contracts/OgvStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ contract OgvStaking is ERC20Votes {
}

function name() public pure override returns (string memory) {
return "Vote Escrowed Origin Dollar Governance";
return "Vote Escrowed Origin DeFi Governance";
}

function symbol() public pure override returns (string memory) {
Expand Down
72 changes: 72 additions & 0 deletions scripts/deploy_005_rebranding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import os

from brownie import *
from brownie.network import priority_fee
from common import *

OGV_PROXY_ADDRESS = "0x9c354503c38481a7a7a51629142963f98ecc12d0"
VEOGV_PROXY_ADDRESS = "0x0c4576ca1c365868e162554af8e385dc3e7c66d9"
REWARDS_PROXY_ADDRESS = "0x7d82e86cf1496f9485a8ea04012afeb3c7489397"
GOVERNANCE_ADDRESS = "0x3cdd07c16614059e66344a7b579dab4f9516c0b6"

def main():
def deployment(deployer, FROM_DEPLOYER, local_provider, is_mainnet, is_fork, is_proposal_mode):
# Existing contracts
veogv_proxy = OgvStakingProxy.at(VEOGV_PROXY_ADDRESS)
ogv_proxy = OriginDollarGovernance.at(OGV_PROXY_ADDRESS)
governance = Governance.at(GOVERNANCE_ADDRESS)

if not is_fork:
# Dynamicly price gas, avoids over paying or TX's getting stuck
priority_fee("2 gwei")

# these values are marked as immutable in the contract and for that reason
# the compiler does not reserve storage slots for them - rather they are
# copied to all the places in the code where they are used. It is important
# that we use the correct values in the constructor
#
# https://docs.soliditylang.org/en/v0.8.17/contracts.html#constant-and-immutable-state-variables
min_staking = 30 * 24 * 60 * 60 # 2592000 -> 30 days
epoch = 1657584000

# Deploy new implementations
veogv_impl = OgvStaking.deploy(OGV_PROXY_ADDRESS, epoch, min_staking, REWARDS_PROXY_ADDRESS, FROM_DEPLOYER)
print("OGVStaking Implementation deployed at {}".format(veogv_impl.address))

ogv_impl = OriginDollarGovernance.deploy(FROM_DEPLOYER)
print("OriginDollarGovernance Implementation deployed at {}".format(ogv_impl.address))

if is_mainnet:
# Verify contract on etherscan on mainnet
print("Verifying contract on Etherscan...")

OgvStaking.publish_source(veogv_impl)
OriginDollarGovernance.publish_source(ogv_impl)

return {
'name': 'Rebrand OGV contracts and adjust governance parameters',
'actions': [
{
'contract': veogv_proxy,
'signature': 'upgradeTo(address)',
'args': [veogv_impl.address]
},
{
'contract': ogv_proxy,
'signature': 'upgradeTo(address)',
'args': [ogv_impl.address]
},
{
'contract': governance,
'signature': 'setVotingPeriod(uint256)',
'args': [BLOCKS_PER_DAY * 2] # 2 days
},
{
'contract': governance,
'signature': 'setLateQuorumVoteExtension(uint64)',
'args': [BLOCKS_PER_DAY * 1] # 1 day
},
]
}

governanceProposal(deployment)
23 changes: 9 additions & 14 deletions tests/test_token.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,55 @@
import brownie
from brownie import *
from .fixtures import token

from .fixtures import token, staking, rewards

def test_name(token):
assert token.name() == "Origin Dollar Governance"

assert token.name() == "Origin DeFi Governance"

def test_symbol(token):
assert token.symbol() == "OGV"

def test_staking_name(staking):
assert staking.name() == "Vote Escrowed Origin DeFi Governance"
shahthepro marked this conversation as resolved.
Show resolved Hide resolved

def test_staking_symbol(staking):
assert staking.symbol() == "veOGV"

def test_decimals(token):
assert token.decimals() == 18


def test_initial_total_supply(token):
assert token.totalSupply() == 1000000000 * 10**18


def test_owner(token):
assert token.owner() == accounts[0]


def test_transfer_ownership(token):
token.transferOwnership(accounts[1])
assert token.owner() == accounts[1]


def test_non_owner_cant_mint(token):
with brownie.reverts(
"AccessControl: account "+accounts[1].address.lower()+" is missing role 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6"
):
token.mint(accounts[1], 100, {"from": accounts[1]})


def test_minter_can_mint(token):
token.grantMinterRole(accounts[0], {"from": accounts[0]})
token.mint(accounts[1], 100, {"from": accounts[0]})
assert token.totalSupply() == 1000000000 * 10**18 + 100


def test_cant_upgrade_to_non_uups(token):
non_uups_token = NonUUPSToken.deploy({"from": accounts[0]})
with brownie.reverts("ERC1967Upgrade: new implementation is not UUPS"):
token.upgradeTo(non_uups_token.address)


def test_upgrade(token):
upgrade_to = TestToken.deploy({"from": accounts[0]})
token.upgradeTo(upgrade_to.address)
token = Contract.from_abi("TestToken", token.address, upgrade_to.abi)
with brownie.reverts("Upgraded"):
token.proof()


def test_non_owner_cant_upgrade(token):
upgrade_to = TestToken.deploy({"from": accounts[0]})
with brownie.reverts("Ownable: caller is not the owner"):
Expand All @@ -69,7 +64,7 @@ def test_burn_from(token):
alice = accounts[0]
bob = accounts[1]

before_balance = token.balanceOf(alice);
before_balance = token.balanceOf(alice)
token.approve(bob, 100, {'from': alice})
token.burnFrom(alice, 100, {'from': bob})
assert before_balance - 100 == token.balanceOf(alice)
Expand All @@ -78,7 +73,7 @@ def test_burn_from_fail_not_approved(token):
alice = accounts[0]
bob = accounts[1]

before_balance = token.balanceOf(alice);
before_balance = token.balanceOf(alice)
token.approve(bob, 90, {'from': alice})
with brownie.reverts("ERC20: insufficient allowance"):
token.burnFrom(alice, 100, {'from': bob})
Loading