Skip to content

Commit

Permalink
add: working mento upgrade for dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sirpy committed Nov 28, 2024
1 parent 732451a commit ba12422
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 53 deletions.
158 changes: 157 additions & 1 deletion contracts/MentoInterfaces.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,170 @@
pragma solidity >=0.8;
pragma experimental ABIEncoderV2;

interface IMentoReserve {
function setTobinTaxStalenessThreshold(uint256) external;

function addToken(address) external returns (bool);

function removeToken(address, uint256) external returns (bool);

function transferGold(address payable, uint256) external returns (bool);

function transferExchangeGold(
address payable,
uint256
) external returns (bool);

function transferCollateralAsset(
address collateralAsset,
address payable to,
uint256 value
) external returns (bool);

function getReserveGoldBalance() external view returns (uint256);

function getUnfrozenReserveGoldBalance() external view returns (uint256);

function getOrComputeTobinTax() external returns (uint256, uint256);

function getTokens() external view returns (address[] memory);

function getReserveRatio() external view returns (uint256);

function addExchangeSpender(address) external;

function removeExchangeSpender(address, uint256) external;

function addSpender(address) external;

function removeSpender(address) external;

function isStableAsset(address) external view returns (bool);

function isCollateralAsset(address) external view returns (bool);

function getDailySpendingRatioForCollateralAsset(
address collateralAsset
) external view returns (uint256);

function isExchangeSpender(address exchange) external view returns (bool);

function addCollateralAsset(address asset) external returns (bool);

function transferExchangeCollateralAsset(
address collateralAsset,
address payable to,
uint256 value
) external returns (bool);

function initialize(
address registryAddress,
uint256 _tobinTaxStalenessThreshold,
uint256 _spendingRatioForCelo,
uint256 _frozenGold,
uint256 _frozenDays,
bytes32[] calldata _assetAllocationSymbols,
uint256[] calldata _assetAllocationWeights,
uint256 _tobinTax,
uint256 _tobinTaxReserveRatio,
address[] calldata _collateralAssets,
uint256[] calldata _collateralAssetDailySpendingRatios
) external;

/// @notice IOwnable:
function transferOwnership(address newOwner) external;

function renounceOwnership() external;

function owner() external view returns (address);

/// @notice Getters:
function registry() external view returns (address);

function tobinTaxStalenessThreshold() external view returns (uint256);

function tobinTax() external view returns (uint256);

function tobinTaxReserveRatio() external view returns (uint256);

function getDailySpendingRatio() external view returns (uint256);

function checkIsCollateralAsset(
address collateralAsset
) external view returns (bool);

function isToken(address) external view returns (bool);

function getOtherReserveAddresses() external view returns (address[] memory);

function getAssetAllocationSymbols() external view returns (bytes32[] memory);

function getAssetAllocationWeights() external view returns (uint256[] memory);

function collateralAssetSpendingLimit(
address
) external view returns (uint256);

function getExchangeSpenders() external view returns (address[] memory);

function getUnfrozenBalance() external view returns (uint256);

function isOtherReserveAddress(
address otherReserveAddress
) external view returns (bool);

function isSpender(address spender) external view returns (bool);

/// @notice Setters:
function setRegistry(address) external;

function setTobinTax(uint256) external;

function setTobinTaxReserveRatio(uint256) external;

function setDailySpendingRatio(uint256 spendingRatio) external;

function setDailySpendingRatioForCollateralAssets(
address[] calldata _collateralAssets,
uint256[] calldata collateralAssetDailySpendingRatios
) external;

function setFrozenGold(uint256 frozenGold, uint256 frozenDays) external;

function setAssetAllocations(
bytes32[] calldata symbols,
uint256[] calldata weights
) external;

function removeCollateralAsset(
address collateralAsset,
uint256 index
) external returns (bool);

function addOtherReserveAddress(
address otherReserveAddress
) external returns (bool);

function removeOtherReserveAddress(
address otherReserveAddress,
uint256 index
) external returns (bool);

function collateralAssets(uint256 index) external view returns (address);

function collateralAssetLastSpendingDay(
address collateralAsset
) external view returns (uint256);
}

interface IBancorExchangeProvider {
struct PoolExchange {
address reserveAsset;
address tokenAddress;
uint256 tokenSupply;
uint256 reserveBalance;
uint32 reserveRatio;
uint32 exitConribution;
uint32 exitContribution;
}

/* ------- Events ------- */
Expand Down
52 changes: 29 additions & 23 deletions contracts/utils/ProtoclUpgradeV4Mento.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity >=0.8.0;

import "../utils/NameService.sol";
import "../Interfaces.sol";
import "../MentoInterfaces.sol";

// import "hardhat/console.sol";

Expand All @@ -11,15 +12,6 @@ interface MentoExchange {
}

contract ProtocolUpgradeV4Mento {
struct PoolExchange {
address reserveAsset;
address tokenAddress;
uint256 tokenSupply;
uint256 reserveBalance;
uint32 reserveRatio;
uint32 exitContribution;
}

address avatar;

constructor(address _avatar) {
Expand All @@ -28,19 +20,35 @@ contract ProtocolUpgradeV4Mento {

function upgrade(
Controller _controller,
PoolExchange memory _exchange,
IBancorExchangeProvider.PoolExchange memory _exchange,
address _mentoExchange,
address _mentoController,
address _distHelper
) external {
require(msg.sender == address(avatar), "only avatar can call this");

uint256 expansionFrequency = 1 days;
uint256 expansionRate = 288617289021952; //10% a year = ((1e18 - expansionRate)/1e18)^365=0.9
uint32 expansionFrequency = 1 days;
uint64 expansionRate = 288617289021952; //10% a year = ((1e18 - expansionRate)/1e18)^365=0.9
uint256 cUSDBalance = ERC20(_exchange.reserveAsset).balanceOf(
MentoExchange(_mentoExchange).reserve()
);
require(cUSDBalance >= 200000e18, "not enough reserve");

(bool ok, bytes memory result) = _controller.genericCall(
MentoExchange(_mentoExchange).reserve(),
abi.encodeCall(IMentoReserve.addToken, _exchange.reserveAsset),
address(avatar),
0
);
require(ok, "addToken cUSD failed");
(ok, result) = _controller.genericCall(
MentoExchange(_mentoExchange).reserve(),
abi.encodeCall(IMentoReserve.addToken, _exchange.tokenAddress),
address(avatar),
0
);
require(ok, "addToken G$ failed");

uint256 gdSupply = ERC20(_exchange.tokenAddress).totalSupply();
uint256 price = 0.0001 ether; // we initialize with price of 0.0001
// given price calculate the reserve ratio
Expand All @@ -54,12 +62,9 @@ contract ProtocolUpgradeV4Mento {
_exchange.reserveRatio = reserveRatio;
_exchange.exitContribution = exitContribution;

(bool ok, bytes memory result) = _controller.genericCall(
(ok, result) = _controller.genericCall(
address(_mentoExchange),
abi.encodeWithSignature(
"createExchange((address,address,uint256,uint256,uint32,uint32))",
_exchange
),
abi.encodeCall(IBancorExchangeProvider.createExchange, _exchange),
address(avatar),
0
);
Expand All @@ -70,11 +75,9 @@ contract ProtocolUpgradeV4Mento {
// console.logBytes32(exchangeId);
(ok, ) = _controller.genericCall(
address(_mentoController),
abi.encodeWithSignature(
"setExpansionConfig(bytes32,uint256,uint256)",
exchangeId,
expansionRate,
expansionFrequency
abi.encodeCall(
IGoodDollarExpansionController.setExpansionConfig,
(exchangeId, expansionRate, expansionFrequency)
),
address(avatar),
0
Expand All @@ -83,7 +86,10 @@ contract ProtocolUpgradeV4Mento {

(ok, ) = _controller.genericCall(
address(_mentoController),
abi.encodeWithSignature("setDistributionHelper(address)", _distHelper),
abi.encodeCall(
IGoodDollarExpansionController.setDistributionHelper,
_distHelper
),
address(avatar),
0
);
Expand Down
11 changes: 6 additions & 5 deletions releases/deployment.json
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,12 @@
"UniswapV3Router": "0x5615CDAb10dc425a742d643d949a7F474C01abc4",
"BuyGDFactory": "0x00e533B7d6255D05b7f15034B1c989c21F51b91C",
"BuyGDFactoryV2": "0x1F60C4C7037C6766924A43666B781ED1479587a2",
"MentoExchangeProvider": "0x02C5e6FfeC49Dca92af50A0718d2c4944DAaCb05",
"MentoExpansionController": "0xA354fE15A08318912D594E94DC7622C7D23Bb11A",
"CUSD": "0x2FFc031e855fE7C36669DC95CE00356D52195999",
"MentoReserve": "0x3f13b9FdB9ca8CDDa1c1E125296C8101B170C37C",
"MentoBroker": "0x43bC03995090E7B4E74cE70deF6bfA27D62049dC",
"MentoExchangeProvider": "0x1ca4F5419B46875C28e9C8259100af76A87a0425",
"MentoCUSDExchangeId": "0x2e04a1379be2d5201bd2ccb939f2dc93c4fd9c23cca80e8c8d658bd0f96fd08d",
"MentoExpansionController": "0x0abA4b83F211ad18921b72BFF3A3E30B97ca2DD7",
"CUSD": "0xeCE55B82251007E478cd261Eb37a6F665EC05737",
"MentoReserve": "0x8E17EC85503C9722f8220C1aeBcE597B0E85fb70",
"MentoBroker": "0x0b8834384b5d8Bb8BD9d50AB24f84E5E90E16E20",
"CeloDistributionHelper": "0x4FE2400B80376a34e6a9011988d9D0D921EEf059"
},
"staging-celo": {
Expand Down
56 changes: 32 additions & 24 deletions scripts/proposals/v4Upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import { executeViaGuardian, executeViaSafe, verifyProductionSigner } from "../m
import ProtocolSettings from "../../releases/deploy-settings.json";

import dao from "../../releases/deployment.json";
import { IGoodDollar } from "../../types";
import { Controller, IBroker, IGoodDollar } from "../../types";
let { name: networkName } = network;

// TODO: import from bridge-contracts package
Expand Down Expand Up @@ -337,11 +337,14 @@ export const upgradeCelo = async network => {
let release: { [key: string]: any } = dao[networkEnv];

let guardian = root;
console.log("signer:", root.address);
console.log("signer:", root.address, { networkEnv });

const cusd = await ethers.getContractAt("IERC20", release.CUSD);
const gd = await ethers.getContractAt("GoodDollar", release.GoodDollar);

//simulate on fork, make sure safe has enough eth to simulate txs
if (isSimulation) {
await reset("https://forno.celo.org");

await reset("https://public-archive-nodes.mainnet.celo-testnet.org/");
await root.sendTransaction({ value: ethers.constants.WeiPerEther.mul(3), to: release.Avatar });

const avatar = await ethers.getImpersonatedSigner(release.Avatar);
Expand All @@ -353,29 +356,21 @@ export const upgradeCelo = async network => {
const eids = await mentoExchange.getExchangeIds();
if (eids.length > 0) {
await mentoExchange.connect(avatar).destroyExchange(eids[0], 0);
// const ctrl = await ethers.getContractAt("Controller", release.Controller);
// const e = mentoExchange.interface.encodeFunctionData("destroyExchange", [eids[0], 0]);
// await ctrl.genericCall(mentoExchange.address, e, release.Avatar, 0);
// console.log("deleted exchage:", eids[0]);
}
try {
await mentoReserve.connect(avatar).addToken(release.CUSD);
await mentoReserve.connect(avatar).addToken(release.GoodDollar);
} catch (e) {
console.log("addToken failed", e);
}
const devCUSD = await ethers.getContractAt(
["function mint(address,uint) external returns (uint)", "function setValidators(address) external"],
release.CUSD
);
await cusd.connect(avatar).transfer(release.MentoReserve, ethers.utils.parseEther("200000"));
await cusd.connect(avatar).transfer(root.address, ethers.utils.parseEther("10000"));

await devCUSD.connect(avatar).setValidators(release.Avatar);
const mintTX = await (
await devCUSD.connect(avatar).mint(release.MentoReserve, ethers.utils.parseEther("200000"))
).wait();
guardian = await ethers.getImpersonatedSigner(release.GuardiansSafe);

await root.sendTransaction({ value: ethers.constants.WeiPerEther.mul(3), to: guardian.address });
} else if (!isProduction) {
const ctrl = (await ethers.getContractAt("Controller", release.Controller)) as Controller;
await ctrl.externalTokenTransfer(
cusd.address,
release.MentoReserve,
ethers.utils.parseEther("200000"),
release.Avatar
);
}

const mpbImplementation = mpbDeployments["42220"].find(_ => _.name === "celo")["MessagePassingBridge_Implementation"]
Expand All @@ -385,7 +380,7 @@ export const upgradeCelo = async network => {
"0xeC577447D314cf1e443e9f4488216651450DBE7c",
"0x6738fA889fF31F82d9Fe8862ec025dbE318f3Fde"
];
const gd = await ethers.getContractAt("GoodDollar", release.GoodDollar);

const ethprovider = new ethers.providers.JsonRpcProvider("https://cloudflare-eth.com");
const fuseprovider = new ethers.providers.JsonRpcProvider("https://rpc.fuse.io");
const TOTAL_LOCKED = (
Expand Down Expand Up @@ -501,14 +496,27 @@ export const upgradeCelo = async network => {
const isBrokerMinter = await gd.isMinter(release.MentoBroker);
const isExpansionMinter = await gd.isMinter(release.MentoExpansionController);
const mentoExchange = await ethers.getContractAt("IBancorExchangeProvider", release.MentoExchangeProvider);
const mentoBroker = (await ethers.getContractAt("IBroker", release.MentoBroker)) as IBroker;
const eids = await mentoExchange.getExchangeIds();
const exchange = await mentoExchange.getPoolExchange(eids[0]);
const price = (await mentoExchange.currentPrice(eids[0])) / 1e18;
console.log("current price:", price);
console.log("Exchange:", exchange);
console.log("Exchange:", exchange, eids[0]);

console.log("Broker minter check:", isBrokerMinter ? "Success" : "Failed");
console.log("Expansion minter check:", isExpansionMinter ? "Success" : "Failed");

console.log(await gd.balanceOf(root.address), await cusd.balanceOf(root.address));
await cusd.approve(release.MentoBroker, ethers.utils.parseEther("1000"));
await mentoBroker.swapIn(
mentoExchange.address,
eids[0],
cusd.address,
gd.address,
ethers.utils.parseEther("1000"),
0
);
console.log(await gd.balanceOf(root.address), await cusd.balanceOf(root.address));
}
};

Expand Down

0 comments on commit ba12422

Please sign in to comment.