Skip to content

Commit

Permalink
Merge pull request #207 from open-dollar/vanity-deploy
Browse files Browse the repository at this point in the history
Vanity deploy
  • Loading branch information
daopunk authored Nov 22, 2023
2 parents 3c7b984 + 08b7376 commit 395fa39
Show file tree
Hide file tree
Showing 26 changed files with 352 additions and 58 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"dependencies": {
"@defi-wonderland/solidity-utils": "0.0.0-4298c6c6",
"@openzeppelin/contracts": "4.8.2",
"@openzeppelin/contracts-upgradeable": "4.8.2",
"@uniswap/v3-periphery": "https://github.com/Uniswap/v3-periphery.git#0.8",
"forge-std": "https://github.com/foundry-rs/forge-std.git#e8a047e3f40f13fa37af6fe14e6e06283d9a060e"
},
Expand Down
1 change: 1 addition & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@defi-wonderland/solidity-utils/=node_modules/@defi-wonderland/solidity-utils/solidity/
@openzeppelin/=node_modules/@openzeppelin/contracts/
@openzeppelin-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/
@uniswap/=node_modules/@uniswap/
@camelot/=lib/core/contracts/
@isolmate/=lib/isolmate/src/
Expand Down
21 changes: 18 additions & 3 deletions script/Common.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ pragma solidity 0.8.19;
import '@script/Contracts.s.sol';
import {Params, ParamChecker, OD, ETH_A, JOB_REWARD} from '@script/Params.s.sol';
import '@script/Registry.s.sol';
import {Create2Factory} from '@contracts/utils/Create2Factory.sol';

abstract contract Common is Contracts, Params {
uint256 internal _deployerPk = 69; // for tests - from HAI
uint256 internal _governorPK;
Create2Factory internal _create2Factory;
uint256 internal salt1;
uint256 internal salt2;
uint256 internal salt3;

function getChainId() public view returns (uint256) {
uint256 id;
Expand Down Expand Up @@ -164,8 +169,14 @@ abstract contract Common is Contracts, Params {

function deployTokenGovernance() public updateParams {
// deploy Tokens
systemCoin = new SystemCoin('Open Dollar', 'OD');
protocolToken = new ProtocolToken('Open Dollar Governance', 'ODG');
// systemCoin = new SystemCoin('Open Dollar', 'OD');
// protocolToken = new ProtocolToken('Open Dollar Governance', 'ODG');
(address systemCoinAddress, address protocolTokenAddress) = _create2Factory.deployTokens(salt1, salt2);
systemCoin = ISystemCoin(systemCoinAddress);
protocolToken = IProtocolToken(protocolTokenAddress);

systemCoin.initialize('Open Dollar', 'OD');
protocolToken.initialize('Open Dollar Governance', 'ODG');

address[] memory members = new address[](0);

Expand Down Expand Up @@ -374,7 +385,11 @@ abstract contract Common is Contracts, Params {
}

function deployProxyContracts() public updateParams {
vault721 = new Vault721(address(timelockController));
// vault721 = new Vault721(address(timelockController));
address vault721Address = _create2Factory.deployVault721(salt3);
vault721 = Vault721(vault721Address);
vault721.initialize(address(timelockController));

safeManager = new ODSafeManager(address(safeEngine), address(vault721));
nftRenderer =
new NFTRenderer(address(vault721), address(oracleRelayer), address(taxCollector), address(collateralJoinFactory));
Expand Down
9 changes: 9 additions & 0 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {Common} from '@script/Common.s.sol';
import {GoerliParams} from '@script/GoerliParams.s.sol';
import {MainnetParams} from '@script/MainnetParams.s.sol';
import {IAlgebraPool} from '@interfaces/oracles/IAlgebraPool.sol';
import {Create2Factory} from '@contracts/utils/Create2Factory.sol';

abstract contract Deploy is Common, Script {
function setupEnvironment() public virtual {}
Expand Down Expand Up @@ -95,6 +96,10 @@ contract DeployMainnet is MainnetParams, Deploy {
function setUp() public virtual {
_deployerPk = uint256(vm.envBytes32('MAINNET_DEPLOYER_PK'));
chainId = 42_161;
_create2Factory = Create2Factory(MAINNET_CREATE2_FACTORY);
salt1 = MAINNET_SALT_SYSTEMCOIN;
salt2 = MAINNET_SALT_PROTOCOLTOKEN;
salt3 = MAINNET_SALT_VAULT721;
}

function mintAirdrop() public virtual override {
Expand Down Expand Up @@ -166,6 +171,10 @@ contract DeployGoerli is GoerliParams, Deploy {
function setUp() public virtual {
_deployerPk = uint256(vm.envBytes32('ARB_SEPOLIA_DEPLOYER_PK'));
chainId = 421_614;
_create2Factory = Create2Factory(SEPOLIA_CREATE2_FACTORY);
salt1 = SEPOLIA_SALT_SYSTEMCOIN;
salt2 = SEPOLIA_SALT_PROTOCOLTOKEN;
salt3 = SEPOLIA_SALT_VAULT721;
}

function mintAirdrop() public virtual override {
Expand Down
31 changes: 24 additions & 7 deletions script/Registry.s.sol
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

// --- Anvil ---
// --- Anvil Local Testnet ---

// Members for governance
address constant ALICE = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; // deployer
address constant BOB = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
address constant CHARLOTTE = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC;

// --- ARB Goerli ---
// --- ARB Sepolia Testnet ---

// Deployment params
uint256 constant MIN_DELAY_GOERLI = 1 minutes;
uint256 constant ORACLE_INTERVAL_TEST = 1 minutes;

// Token contracts
address constant GOERLI_WETH = 0xEe01c0CD76354C383B8c7B4e65EA88D00B06f36f;
address constant GOERLI_GOV_TOKEN = 0x0Ed89D4655b2fE9f99EaDC3116b223527165452D;

// Members for governance
address constant H = 0x37c5B029f9c3691B3d47cb024f84E5E257aEb0BB;
address constant J = 0xcb81A76a565aC4870EDA5B0e32c5a0D2ec734174;
address constant P = 0xC295763Eed507d4A0f8B77241c03dd3354781a15;

// Vanity address params - use `cast create2` to find salt
uint256 constant SEPOLIA_SALT_SYSTEMCOIN =
112_897_861_258_990_387_098_776_944_447_239_821_066_355_482_563_138_389_422_987_534_236_459_546_050_026;
uint256 constant SEPOLIA_SALT_PROTOCOLTOKEN =
33_909_640_905_358_342_898_143_724_624_030_133_083_920_609_190_925_545_591_963_391_866_995_498_083_907;
uint256 constant SEPOLIA_SALT_VAULT721 =
53_108_215_892_343_944_041_352_961_460_150_983_644_958_469_624_782_417_283_725_833_369_029_472_088_009;
address constant SEPOLIA_CREATE2_FACTORY = 0x196eFA212f88C2Dd7f0a74E747168B3A37F335c0;

// --- ARB Goerli Testnet ---

// Token contracts
address constant GOERLI_WETH = 0xEe01c0CD76354C383B8c7B4e65EA88D00B06f36f;
address constant GOERLI_GOV_TOKEN = 0x0Ed89D4655b2fE9f99EaDC3116b223527165452D;
// Chainlink feeds
address constant GOERLI_CHAINLINK_ETH_USD_FEED = 0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08;
address constant GOERLI_CHAINLINK_ARB_USD_FEED = 0x2eE9BFB2D319B31A573EA15774B755715988E99D;

// Liquidity pools
address constant GOERLI_UNISWAP_V3_FACTORY = 0x4893376342d5D7b3e31d4184c08b265e5aB2A3f6;
address constant GOERLI_CAMELOT_V2_FACTORY = 0x659fd9F4536f540bd051c2739Fc8b8e9355E5042;
Expand All @@ -39,6 +50,12 @@ uint256 constant AIRDROP_AMOUNT = 10_000e18; // 10k tokens
uint256 constant MIN_DELAY = 3 days; // timelock for governor
uint256 constant ORACLE_INTERVAL_PROD = 1 hours;

// Vanity address params - use `cast create2` to find salt
uint256 constant MAINNET_SALT_SYSTEMCOIN = 0;
uint256 constant MAINNET_SALT_PROTOCOLTOKEN = 0;
uint256 constant MAINNET_SALT_VAULT721 = 0;
address constant MAINNET_CREATE2_FACTORY = address(0);

// Token contracts (all 18 decimals)
address constant ARBITRUM_WSTETH = 0x5979D7b546E38E414F7E9822514be443A4800529;
address constant ARBITRUM_ARB = 0x912CE59144191C1204E64559FE8253a0e49E6548;
Expand Down
23 changes: 23 additions & 0 deletions script/create2/DeployContracts.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import '@script/Registry.s.sol';
import {Script} from 'forge-std/Script.sol';
import {Create2Factory} from '@contracts/utils/Create2Factory.sol';

// BROADCAST
// source .env && forge script DeployContracts --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY

// SIMULATE
// source .env && forge script DeployContracts --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC

contract DeployContracts is Script {
Create2Factory create2Factory = Create2Factory(SEPOLIA_CREATE2_FACTORY);

function run() public {
vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK'));
create2Factory.deployTokens(SEPOLIA_SALT_SYSTEMCOIN, SEPOLIA_SALT_PROTOCOLTOKEN);
create2Factory.deployVault721(SEPOLIA_SALT_VAULT721);
vm.stopBroadcast();
}
}
19 changes: 19 additions & 0 deletions script/create2/DeployCreate2Factory.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import {Script} from 'forge-std/Script.sol';
import {Create2Factory} from '@contracts/utils/Create2Factory.sol';

// BROADCAST
// source .env && forge script DeployCreate2Factory --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC --broadcast --verify --etherscan-api-key $ARB_ETHERSCAN_API_KEY

// SIMULATE
// source .env && forge script DeployCreate2Factory --with-gas-price 2000000000 -vvvvv --rpc-url $ARB_SEPOLIA_RPC

contract DeployCreate2Factory is Script {
function run() public {
vm.startBroadcast(vm.envUint('ARB_SEPOLIA_DEPLOYER_PK'));
new Create2Factory();
vm.stopBroadcast();
}
}
4 changes: 2 additions & 2 deletions src/contracts/SurplusAuctionHouse.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {Authorizable} from '@contracts/utils/Authorizable.sol';
import {Modifiable} from '@contracts/utils/Modifiable.sol';
import {Disableable} from '@contracts/utils/Disableable.sol';

import {SafeERC20} from '@openzeppelin/token/ERC20/utils/SafeERC20.sol';
import {SafeERC20Upgradeable} from '@openzeppelin-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';
import {Encoding} from '@libraries/Encoding.sol';
import {Assertions} from '@libraries/Assertions.sol';
import {Math, WAD} from '@libraries/Math.sol';
Expand All @@ -23,7 +23,7 @@ contract SurplusAuctionHouse is Authorizable, Modifiable, Disableable, ISurplusA
using Math for uint256;
using Encoding for bytes;
using Assertions for address;
using SafeERC20 for IProtocolToken;
using SafeERC20Upgradeable for IProtocolToken;

/// @inheritdoc ICommonSurplusAuctionHouse
bytes32 public constant AUCTION_HOUSE_TYPE = bytes32('SURPLUS');
Expand Down
18 changes: 15 additions & 3 deletions src/contracts/proxies/Vault721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
pragma solidity 0.8.19;

import {ERC721} from '@openzeppelin/token/ERC721/ERC721.sol';
import {ERC721Enumerable} from '@openzeppelin/token/ERC721/extensions/ERC721Enumerable.sol';
import {ERC721EnumerableUpgradeable} from
'@openzeppelin-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol';
import {IODSafeManager} from '@interfaces/proxies/IODSafeManager.sol';
import {ODProxy} from '@contracts/proxies/ODProxy.sol';
import {NFTRenderer} from '@contracts/proxies/NFTRenderer.sol';

// Open Dollar
// Version 1.5.8

contract Vault721 is ERC721Enumerable {
/**
* @notice Upgradeable contract used as singleton, but is not upgradeable
*/
contract Vault721 is ERC721EnumerableUpgradeable {
error NotGovernor();
error ProxyAlreadyExist();
error ZeroAddress();
Expand All @@ -27,11 +31,19 @@ contract Vault721 is ERC721Enumerable {

event CreateProxy(address indexed _user, address _proxy);

/**
* @dev initializer preferred for CREATE2 deployment
*/
constructor() {
_disableInitializers();
}

/**
* @dev initializes DAO timelockController contract
*/
constructor(address _timelockController) ERC721('OpenDollar Vault', 'ODV') {
function initialize(address _timelockController) external initializer {
timelockController = _timelockController;
__ERC721_init('OpenDollar Vault', 'ODV');
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/contracts/proxies/actions/CommonActions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity 0.8.19;

import {ISAFEEngine} from '@interfaces/ISAFEEngine.sol';
import {IERC20Metadata} from '@openzeppelin/token/ERC20/extensions/IERC20Metadata.sol';
import {IERC20MetadataUpgradeable} from '@openzeppelin-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol';
import {ICoinJoin} from '@interfaces/utils/ICoinJoin.sol';
import {ICollateralJoin} from '@interfaces/utils/ICollateralJoin.sol';
import {ICommonActions} from '@interfaces/proxies/actions/ICommonActions.sol';
Expand Down Expand Up @@ -51,7 +52,7 @@ abstract contract CommonActions is ICommonActions {
if (_wad == 0) return;

// NOTE: assumes systemCoin uses 18 decimals
IERC20Metadata _systemCoin = ICoinJoin(_coinJoin).systemCoin();
IERC20MetadataUpgradeable _systemCoin = ICoinJoin(_coinJoin).systemCoin();
// Transfers coins from the user to the proxy
_systemCoin.transferFrom(msg.sender, address(this), _wad);
// Approves adapter to take the COIN amount
Expand Down
8 changes: 4 additions & 4 deletions src/contracts/proxies/actions/DebtBidActions.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import {IERC20Metadata} from '@openzeppelin/token/ERC20/extensions/IERC20Metadata.sol';
import {IERC20MetadataUpgradeable} from '@openzeppelin-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol';
import {IAccountingEngine} from '@interfaces/IAccountingEngine.sol';
import {IDebtAuctionHouse} from '@interfaces/IDebtAuctionHouse.sol';
import {ISAFEEngine} from '@interfaces/ISAFEEngine.sol';
Expand Down Expand Up @@ -50,7 +50,7 @@ contract DebtBidActions is CommonActions, IDebtBidActions {

if (_auction.highBidder == address(this)) {
// get the amount of protocol tokens that were sold
IERC20Metadata _protocolToken = IDebtAuctionHouse(_debtAuctionHouse).protocolToken();
IERC20MetadataUpgradeable _protocolToken = IDebtAuctionHouse(_debtAuctionHouse).protocolToken();
_protocolToken.transfer(msg.sender, _auction.amountToSell);
}

Expand All @@ -65,7 +65,7 @@ contract DebtBidActions is CommonActions, IDebtBidActions {
/// @inheritdoc IDebtBidActions
function collectProtocolTokens(address _protocolToken) external delegateCall {
// get the amount of protocol tokens that the proxy has
uint256 _coinsToCollect = IERC20Metadata(_protocolToken).balanceOf(address(this));
IERC20Metadata(_protocolToken).transfer(msg.sender, _coinsToCollect);
uint256 _coinsToCollect = IERC20MetadataUpgradeable(_protocolToken).balanceOf(address(this));
IERC20MetadataUpgradeable(_protocolToken).transfer(msg.sender, _coinsToCollect);
}
}
4 changes: 2 additions & 2 deletions src/contracts/proxies/actions/SurplusBidActions.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import {IERC20Metadata} from '@openzeppelin/token/ERC20/extensions/IERC20Metadata.sol';
import {IERC20MetadataUpgradeable} from '@openzeppelin-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol';
import {IAccountingEngine} from '@interfaces/IAccountingEngine.sol';
import {ISurplusAuctionHouse} from '@interfaces/ISurplusAuctionHouse.sol';
import {ISAFEEngine} from '@interfaces/ISAFEEngine.sol';
Expand All @@ -24,7 +24,7 @@ contract SurplusBidActions is ISurplusBidActions, CommonActions {
uint256 _amountToSell = ISurplusAuctionHouse(_surplusAuctionHouse).auctions(_auctionId).amountToSell;

// prepare protocol token spending
IERC20Metadata _protocolToken = ISurplusAuctionHouse(_surplusAuctionHouse).protocolToken();
IERC20MetadataUpgradeable _protocolToken = ISurplusAuctionHouse(_surplusAuctionHouse).protocolToken();
_protocolToken.transferFrom(msg.sender, address(this), _bidAmount);
_protocolToken.approve(address(_surplusAuctionHouse), _bidAmount);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {IProtocolToken} from '@interfaces/tokens/IProtocolToken.sol';
import {Authorizable} from '@contracts/utils/Authorizable.sol';
import {Modifiable} from '@contracts/utils/Modifiable.sol';

import {SafeERC20} from '@openzeppelin/token/ERC20/utils/SafeERC20.sol';
import {SafeERC20Upgradeable} from '@openzeppelin-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol';
import {Encoding} from '@libraries/Encoding.sol';
import {WAD} from '@libraries/Math.sol';
import {Assertions} from '@libraries/Assertions.sol';
Expand All @@ -23,7 +23,7 @@ import {Assertions} from '@libraries/Assertions.sol';
*/
contract PostSettlementSurplusAuctionHouse is Authorizable, Modifiable, IPostSettlementSurplusAuctionHouse {
using Encoding for bytes;
using SafeERC20 for IProtocolToken;
using SafeERC20Upgradeable for IProtocolToken;
using Assertions for address;

bytes32 public constant AUCTION_HOUSE_TYPE = bytes32('SURPLUS');
Expand Down
23 changes: 16 additions & 7 deletions src/contracts/tokens/ProtocolToken.sol
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.19;

import {ERC20Votes, ERC20Permit, ERC20} from '@openzeppelin/token/ERC20/extensions/ERC20Votes.sol';
import {Authorizable} from '@contracts/utils/Authorizable.sol';
import {
ERC20VotesUpgradeable,
ERC20PermitUpgradeable,
ERC20Upgradeable
} from '@openzeppelin-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol';
import {AuthorizableUpgradeable} from '@contracts/utils/AuthorizableUpgradeable.sol';

import {IProtocolToken} from '@interfaces/tokens/IProtocolToken.sol';

/**
* @title ProtocolToken
* @notice This contract represents the protocol ERC20Votes token to be used for governance purposes
*/
contract ProtocolToken is ERC20Votes, Authorizable, IProtocolToken {
contract ProtocolToken is ERC20VotesUpgradeable, AuthorizableUpgradeable, IProtocolToken {
// --- Init ---

constructor() {
_disableInitializers();
}

/**
* @param _name String with the name of the token
* @param _symbol String with the symbol of the token
*/
constructor(
string memory _name,
string memory _symbol
) ERC20(_name, _symbol) ERC20Permit(_name) Authorizable(msg.sender) {}
function initialize(string memory _name, string memory _symbol) external initializer {
__ERC20_init(_name, _symbol);
__ERC20Permit_init(_name);
__authorizable_init(msg.sender);
}

// --- Methods ---

Expand Down
Loading

0 comments on commit 395fa39

Please sign in to comment.