Skip to content

Commit

Permalink
add: eth reserve restore upgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
sirpy committed Sep 26, 2024
1 parent 7d9c65c commit 3b89ff3
Show file tree
Hide file tree
Showing 3 changed files with 620 additions and 0 deletions.
123 changes: 123 additions & 0 deletions contracts/utils/FuseOldBridgeKill.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8;

import "../Interfaces.sol";

interface IUpgradeabilityOwnerStorage {
function upgradeabilityOwner() external view returns (address);
}

contract Upgradeable {
// Avoid using onlyUpgradeabilityOwner name to prevent issues with implementation from proxy contract
modifier onlyIfUpgradeabilityOwner() {
require(
msg.sender ==
IUpgradeabilityOwnerStorage(address(this)).upgradeabilityOwner()
);
/* solcov ignore next */
_;
}
}

/**
* @title EternalStorage
* @dev This contract holds all the necessary state variables to carry out the storage of any contract.
*/
contract EternalStorage {
mapping(bytes32 => uint256) internal uintStorage;
mapping(bytes32 => string) internal stringStorage;
mapping(bytes32 => address) internal addressStorage;
mapping(bytes32 => bytes) internal bytesStorage;
mapping(bytes32 => bool) internal boolStorage;
mapping(bytes32 => int256) internal intStorage;
}

/**
* @title Ownable
* @dev This contract has an owner address providing basic authorization control
*/
contract Ownable is EternalStorage {
bytes4 internal constant UPGRADEABILITY_OWNER = 0x6fde8202; // upgradeabilityOwner()

/**
* @dev Event to show ownership has been transferred
* @param previousOwner representing the address of the previous owner
* @param newOwner representing the address of the new owner
*/
event OwnershipTransferred(address previousOwner, address newOwner);

/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner());
/* solcov ignore next */
_;
}

/**
* @dev Throws if called by any account other than contract itself or owner.
*/
modifier onlyRelevantSender() {
// proxy owner if used through proxy, address(0) otherwise
(bool ok, bytes memory addr) = address(this).call(
abi.encodeWithSelector(UPGRADEABILITY_OWNER)
);
address upgowner = abi.decode(addr, (address));
require(
(ok && upgowner != address(0)) || // covers usage without calling through storage proxy
msg.sender ==
IUpgradeabilityOwnerStorage(address(this)).upgradeabilityOwner() || // covers usage through regular proxy calls
msg.sender == address(this) // covers calls through upgradeAndCall proxy method
);
/* solcov ignore next */
_;
}

bytes32 internal constant OWNER =
0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; // keccak256(abi.encodePacked("owner"))

/**
* @dev Tells the address of the owner
* @return the address of the owner
*/
function owner() public view returns (address) {
return addressStorage[OWNER];
}

/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner the address to transfer ownership to.
*/
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0));
setOwner(newOwner);
}

/**
* @dev Sets a new owner address
*/
function setOwner(address newOwner) internal {
emit OwnershipTransferred(owner(), newOwner);
addressStorage[OWNER] = newOwner;
}
}

contract Initializable is EternalStorage {
bytes32 internal constant INITIALIZED =
0x0a6f646cd611241d8073675e00d1a1ff700fbf1b53fcf473de56d1e6e4b714ba; // keccak256(abi.encodePacked("isInitialized"))

function setInitialize() internal {
boolStorage[INITIALIZED] = true;
}

function isInitialized() public view returns (bool) {
return boolStorage[INITIALIZED];
}
}

contract FuseOldBridgeKill is Initializable, Upgradeable {
function end() external {
IGoodDollar(0x495d133B938596C9984d462F007B676bDc57eCEC).renounceMinter();
}
}
94 changes: 94 additions & 0 deletions contracts/utils/ReserveRestore.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import "../utils/NameService.sol";
import "../Interfaces.sol";
import "../reserve/GoodReserveCDai.sol";
import "hardhat/console.sol";

contract ReserveRestore {
NameService ns;
uint256 public constant LOCKED_HACKED_FUNDS = 971921364208;

constructor(NameService _ns) {
ns = _ns;
}

function upgrade() external {
address avatar = ns.dao().avatar();

GoodReserveCDai reserve = GoodReserveCDai(ns.getAddress("RESERVE"));
uint256 daiBalance = ERC20(ns.getAddress("DAI")).balanceOf(address(this));
require(daiBalance >= 200000e18, "not enough reserve");
cERC20 cdai = cERC20(ns.getAddress("CDAI"));
ERC20 dai = ERC20(ns.getAddress("DAI"));

dai.approve(address(cdai), daiBalance);
//Mint cDAIs
uint256 cDaiResult = cdai.mint(daiBalance);
require(cDaiResult == 0, "Minting cDai failed");
uint256 cdaiBalance = cdai.balanceOf(address(this));
require(cdaiBalance > 0, "not cdai minted");
cdai.transfer(address(reserve), cdaiBalance);
cdaiBalance = cdai.balanceOf(address(reserve));

uint256 gdSupply = ERC20(ns.getAddress("GOODDOLLAR")).totalSupply() -
LOCKED_HACKED_FUNDS;
console.log("supply: %s", gdSupply);
// get 0.00001 dai price in cdai
uint256 initialPriceCdai = (0.0001 * 1e8 * 1e28) /
cdai.exchangeRateStored(); //excghange rate is at 1e28 precision rate/1e28=1 cdai price in dai mul by 1e8 to get in cdai precision
console.log("initialPriceCdai: %s", initialPriceCdai);

console.log("cdaiBalance: %s", cdaiBalance);

// given price calculate the reserve ratio
uint32 reserveRatio = uint32(
(cdaiBalance * 1e2 * 1e6) / (initialPriceCdai * gdSupply)
); // mul by 1e2 to cover gd precision, cdaibalance precision=initialprice, mul by 1e6 to receive result in the precision of reserveRatio(1e6)
console.log("reserveRatio: %s", reserveRatio);
Controller ctrl = Controller(ns.getAddress("CONTROLLER"));
// function initializeToken(
// ERC20 _token,
// uint256 _gdSupply,
// uint256 _tokenSupply,
// uint32 _reserveRatio,
// uint256 _lastExpansion
// )
(bool ok, ) = ctrl.genericCall(
address(reserve.getMarketMaker()),
abi.encodeCall(
GoodMarketMaker.initializeToken,
(cdai, gdSupply, cdaiBalance, reserveRatio, block.timestamp)
),
address(avatar),
0
);
require(ok, "initializeToken failed");
// ContributionCalc(
// ns.getAddress("CONTRIBUTION_CALCULATION")
// ).setContributionRatio(0.1*1e18,1e18);

// exit contribution to 10%
(ok, ) = ctrl.genericCall(
address(ns.getAddress("CONTRIBUTION_CALCULATION")),
abi.encodeCall(ContributionCalc.setContributionRatio, (0.1 * 1e18, 1e18)),
address(avatar),
0
);
require(ok, "setContributionRatio failed");

(ok, ) = ctrl.genericCall(
address(reserve),
abi.encodeCall(GoodReserveCDai.setGDXDisabled, (true, true)),
address(avatar),
0
);

require(ok, "setContributionRatio failed");

// prevent executing again
require(ctrl.unregisterSelf(avatar), "unregistering failed");
selfdestruct(payable(msg.sender));
}
}
Loading

0 comments on commit 3b89ff3

Please sign in to comment.