Skip to content

Commit

Permalink
Deploy and configure trustee fee collection (#543)
Browse files Browse the repository at this point in the history
* configuration for the trustee

* remove test goof up

* Add deploy 13

* Add hardhat yield task

* Add OUSDReset to ignore list for etherscan verify; fix deploy 13 dependency
  • Loading branch information
Franck authored Feb 3, 2021
1 parent 68ff1ad commit d2231cd
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 2 deletions.
117 changes: 117 additions & 0 deletions contracts/deploy/013_trustee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
const {
isMainnet,
isFork,
isRinkeby,
isSmokeTest,
} = require("../test/helpers.js");
const {
log,
deployWithConfirmation,
withConfirmation,
executeProposal,
sendProposal,
} = require("../utils/deploy");
const { proposeArgs } = require("../utils/governor");
const { getTxOpts } = require("../utils/tx");

const deployName = "013_upgrades";

/**
* Deploys the vault trustee feature:
* - upgrade VaultCore
* - set trusteeAdress and trusteeFeeBps
* @returns {Promise<boolean>}
*/
const trustee = async (hre) => {
console.log(`Running ${deployName} deployment...`);

const { governorAddr } = await hre.getNamedAccounts();

// Signers
const sGovernor = await ethers.provider.getSigner(governorAddr);

const cVaultProxy = await ethers.getContract("VaultProxy");
const cvaultAdmin = await ethers.getContractAt(
"VaultAdmin",
cVaultProxy.address
);

// Deploy a new VaultCore contract.
const dVaultCore = await deployWithConfirmation("VaultCore");

// Proposal for the governor to do the upgrades.
const propDescription = "Trustee deploy and config";
const trusteeAddress = "0xF14BBdf064E3F67f51cd9BD646aE3716aD938FDC"; // Strategist multi-sig
const trusteeFeeBps = 1000; // 1000 bps = 10%
const propArgs = await proposeArgs([
{
contract: cVaultProxy,
signature: "upgradeTo(address)",
args: [dVaultCore.address],
},
{
contract: cvaultAdmin,
signature: "setTrusteeAddress(address)",
args: [trusteeAddress],
},
{
contract: cvaultAdmin,
signature: "setTrusteeFeeBps(uint256)",
args: [trusteeFeeBps],
},
]);

if (isMainnet) {
// On Mainnet, only propose. The enqueue and execution are handled manually via multi-sig.
log("Sending proposal to governor...");
await sendProposal(propArgs, propDescription);
log("Proposal sent.");
} else if (isFork) {
// On Fork we can send the proposal then impersonate the guardian to execute it.
log("Sending and executing proposal...");
await executeProposal(propArgs, propDescription);
log("Proposal executed.");
} else {
// Hardcoding gas estimate on Rinkeby since it fails for an undetermined reason...
const gasLimit = isRinkeby ? 1000000 : null;

await withConfirmation(
cVaultProxy
.connect(sGovernor)
.upgradeTo(dVaultCore.address, await getTxOpts(gasLimit))
);
log("Upgraded VaultCore to new implementation");

await withConfirmation(
cvaultAdmin
.connect(sGovernor)
.setTrusteeAddress(trusteeAddress, await getTxOpts(gasLimit))
);
log("Trustee address set");

await withConfirmation(
cvaultAdmin
.connect(sGovernor)
.setTrusteeFeeBps(trusteeFeeBps, await getTxOpts(gasLimit))
);
log("Trustee fee bps set");
}

return true;
};

const main = async (hre) => {
console.log(`Running ${deployName} deployment...`);
if (!hre) {
hre = require("hardhat");
}
await trustee(hre);
console.log(`${deployName} deploy done.`);
return true;
};

main.id = deployName;
main.dependencies = ["012_upgrades"];
main.skip = () => !(isMainnet || isRinkeby || isFork) || isSmokeTest;

module.exports = main;
2 changes: 2 additions & 0 deletions contracts/hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const {
harvest,
reallocate,
rebase,
yield,
} = require("./tasks/vault");

const MAINNET_DEPLOYER = "0x71F78361537A6f7B6818e7A760c8bC0146D93f50";
Expand Down Expand Up @@ -87,6 +88,7 @@ task("allocate", "Call allocate() on the Vault", allocate);
task("capital", "Set the Vault's pauseCapital flag", capital);
task("harvest", "Call harvest() on Vault", harvest);
task("rebase", "Call rebase() on the Vault", rebase);
task("yield", "Artificially generate yield on the Vault", yield);
task("reallocate", "Allocate assets from one Strategy to another")
.addParam("from", "Address to withdraw asset from")
.addParam("to", "Address to deposit asset to")
Expand Down
1 change: 1 addition & 0 deletions contracts/scripts/etherscan/etherscanVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const deprecatedContractNames = [
"MinuteTimelock",
"OpenUniswapOracle",
"RebaseHooks",
"OUSDReset",
];

function logError(...args) {
Expand Down
8 changes: 6 additions & 2 deletions contracts/tasks/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ async function debug(taskArguments, hre) {
//
const rebasePaused = await vault.rebasePaused();
const capitalPaused = await vault.capitalPaused();
const redeemFeeBps = await vault.redeemFeeBps();
const redeemFeeBps = Number(await vault.redeemFeeBps());
const trusteeFeeBps = Number(await vault.trusteeFeeBps());
const vaultBuffer = await vault.vaultBuffer();
const autoAllocateThreshold = await vault.autoAllocateThreshold();
const rebaseThreshold = await vault.rebaseThreshold();
Expand All @@ -233,12 +234,14 @@ async function debug(taskArguments, hre) {
const strategyCount = await vault.getStrategyCount();
const assetCount = await vault.getAssetCount();
const strategistAddress = await vault.strategistAddr();
const trusteeAddress = await vault.trusteeAddress();

console.log("\nVault Settings");
console.log("================");
console.log("rebasePaused:\t\t\t", rebasePaused);
console.log("capitalPaused:\t\t\t", capitalPaused);
console.log("redeemFeeBps:\t\t\t", redeemFeeBps.toString());
console.log(`redeemFeeBps:\t\t\t ${redeemFeeBps} (${redeemFeeBps / 100}%)`);
console.log(`trusteeFeeBps:\t\t\t ${trusteeFeeBps} (${trusteeFeeBps / 100}%)`);
console.log("vaultBuffer:\t\t\t", formatUnits(vaultBuffer.toString(), 18));
console.log(
"autoAllocateThreshold (USD):\t",
Expand All @@ -254,6 +257,7 @@ async function debug(taskArguments, hre) {
console.log("Strategy count:\t\t\t", Number(strategyCount));
console.log("Asset count:\t\t\t", Number(assetCount));
console.log("Strategist address:\t\t", strategistAddress);
console.log("Trustee address:\t\t", trusteeAddress)

const assets = [
{
Expand Down
58 changes: 58 additions & 0 deletions contracts/tasks/vault.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,63 @@ async function rebase(taskArguments, hre) {
console.log("Rebase transaction confirmed");
}

/**
* Artificially generate yield on the vault by sending it USDT.
*/
async function yield(taskArguments, hre) {
const usdtAbi = require("../test/abi/usdt.json").abi;
const {
ousdUnitsFormat,
usdtUnits,
usdtUnitsFormat,
isFork,
isLocalhost
} = require("../test/helpers");
if (!isFork && !isLocalhost) {
throw new Error('Task can only be used on local or fork')
}

let richSigner, usdt;
if (isFork) {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [addresses.mainnet.Binance],
});
richSigner = await hre.ethers.provider.getSigner(
addresses.mainnet.Binance
);
usdt = await hre.ethers.getContractAt(usdtAbi, addresses.mainnet.USDT);
} else {
const signers = await hre.ethers.getSigners();
richSigner = signers
usdt = await hre.ethers.getContract("MockUSDT");
}

const vaultProxy = await ethers.getContract("VaultProxy");
const vault = await ethers.getContractAt("IVault", vaultProxy.address);

const ousdProxy = await ethers.getContract("OUSDProxy");
const ousd = await ethers.getContractAt("OUSD", ousdProxy.address);

console.log("Sending yield to vault")
let usdtBalance = await usdt.balanceOf(vaultProxy.address)
console.log("USDT vault balance", usdtUnitsFormat(usdtBalance))
let vaultValue = await vault.totalValue()
console.log("Vault value", ousdUnitsFormat(vaultValue))
let supply = await ousd.totalSupply();
console.log("OUSD supply", ousdUnitsFormat(supply))

// Transfer 100k USDT to the vault.
await usdt.connect(richSigner).transfer(vaultProxy.address, usdtUnits("100000"));

usdtBalance = await usdt.balanceOf(vaultProxy.address)
console.log("USDT vault balance", usdtUnitsFormat(usdtBalance))
vaultValue = await vault.totalValue()
console.log("Vault value", ousdUnitsFormat(vaultValue))
supply = await ousd.totalSupply();
console.log("OUSD supply", ousdUnitsFormat(supply))
}

/**
* Call the Vault's admin pauseCapital method.
*/
Expand Down Expand Up @@ -231,4 +288,5 @@ module.exports = {
harvest,
reallocate,
rebase,
yield,
}

0 comments on commit d2231cd

Please sign in to comment.