Skip to content

Commit

Permalink
checkpoint: organization, clean up TODO's
Browse files Browse the repository at this point in the history
Signed-off-by: Elliot <elliotfriedman3@gmail.com>
  • Loading branch information
ElliotFriedman committed Nov 6, 2024
1 parent 50648e6 commit aecfda8
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 150 deletions.
7 changes: 3 additions & 4 deletions src/exercises/00/SIP00.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {Addresses} from
"@forge-proposal-simulator/addresses/Addresses.sol";

import {Vault} from "src/exercises/00/Vault00.sol";
import {MockToken} from "@mocks/MockToken.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";

/// DO_RUN=false DO_BUILD=false DO_DEPLOY=true DO_SIMULATE=false DO_PRINT=false DO_VALIDATE=true forge script src/exercises/00/SIP00.sol:SIP00 -vvvv
Expand Down Expand Up @@ -50,20 +49,20 @@ contract SIP00 is GovernorBravoProposal {
}

function deploy() public override {
if (!addresses.isAddressSet("V1_VAULT")) {
if (!addresses.isAddressSet("V0_VAULT")) {
address[] memory tokens = new address[](3);
tokens[0] = addresses.getAddress("USDC");
tokens[1] = addresses.getAddress("DAI");
tokens[2] = addresses.getAddress("USDT");

Vault vault = new Vault(tokens);

addresses.addAddress("V1_VAULT", address(vault), true);
addresses.addAddress("V0_VAULT", address(vault), true);
}
}

function validate() public view override {
Vault vault = Vault(addresses.getAddress("V1_VAULT"));
Vault vault = Vault(addresses.getAddress("V0_VAULT"));

assertEq(
vault.authorizedToken(addresses.getAddress("USDC")),
Expand Down
1 change: 0 additions & 1 deletion src/exercises/01/SIP01.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {Addresses} from
"@forge-proposal-simulator/addresses/Addresses.sol";

import {Vault} from "src/exercises/01/Vault01.sol";
import {MockToken} from "@mocks/MockToken.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";

/// DO_RUN=false DO_BUILD=false DO_DEPLOY=true DO_SIMULATE=false DO_PRINT=false DO_VALIDATE=true forge script src/exercises/01/SIP01.sol:SIP01 -vvvv
Expand Down
70 changes: 7 additions & 63 deletions src/exercises/02/SIP02.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ import {GovernorBravoProposal} from
"@forge-proposal-simulator/src/proposals/GovernorBravoProposal.sol";
import {Addresses} from
"@forge-proposal-simulator/addresses/Addresses.sol";

import {Vault03} from "src/exercises/03/Vault.sol";
import {Vault04} from "src/exercises/04/Vault04.sol";
import {MockToken} from "@mocks/MockToken.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";
import {
ProxyAdmin,
TransparentUpgradeableProxy,
Expand All @@ -20,6 +15,9 @@ import {ERC1967Utils} from
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {Vault} from "src/exercises/02/Vault02.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";

/// DO_RUN=false DO_BUILD=false DO_DEPLOY=true DO_SIMULATE=false DO_PRINT=false DO_VALIDATE=true forge script src/exercises/02/SIP02.sol:SIP02 -vvvv
contract SIP02 is GovernorBravoProposal {
using ForkSelector for uint256;
Expand Down Expand Up @@ -60,64 +58,21 @@ contract SIP02 is GovernorBravoProposal {
}

function deploy() public override {
address vaultProxy;
if (!addresses.isAddressSet("V3_VAULT_IMPLEMENTATION")) {
address vaultImpl = address(new Vault03());
addresses.addAddress(
"V3_VAULT_IMPLEMENTATION", vaultImpl, true
);

if (!addresses.isAddressSet("V2_VAULT")) {
address[] memory tokens = new address[](3);
tokens[0] = addresses.getAddress("USDC");
tokens[1] = addresses.getAddress("DAI");
tokens[2] = addresses.getAddress("USDT");

address owner = addresses.getAddress("DEPLOYER_EOA");

// Generate calldata for initialize function of vault
bytes memory data = abi.encodeWithSignature(
"initialize(address[],address)", tokens, owner
);

vaultProxy = address(
new TransparentUpgradeableProxy(
vaultImpl, owner, data
)
);
addresses.addAddress("VAULT_PROXY", vaultProxy, true);
}

if (!addresses.isAddressSet("V4_VAULT_IMPLEMENTATION")) {
address vaultImpl = address(new Vault04());
addresses.addAddress(
"V4_VAULT_IMPLEMENTATION", vaultImpl, true
);
address vaultImpl = address(new Vault(tokens, owner));
addresses.addAddress("V2_VAULT", vaultImpl, true);
}
}

function build()
public
override
buildModifier(addresses.getAddress("COMPOUND_TIMELOCK_BRAVO"))
{
address vaultProxy = addresses.getAddress("VAULT_PROXY");
bytes32 adminSlot =
vm.load(vaultProxy, ERC1967Utils.ADMIN_SLOT);

address proxyAdmin = address(uint160(uint256(adminSlot)));

// upgrade to new implementation
ProxyAdmin(proxyAdmin).upgradeAndCall(
ITransparentUpgradeableProxy(vaultProxy),
addresses.getAddress("V4_VAULT_IMPLEMENTATION"),
""
);

Vault04(vaultProxy).setMaxSupply(1_000_000e18);
}

function validate() public view override {
Vault04 vault = Vault04(addresses.getAddress("VAULT_PROXY"));
Vault vault = Vault(addresses.getAddress("V2_VAULT"));

assertEq(
vault.authorizedToken(addresses.getAddress("USDC")),
Expand All @@ -134,16 +89,5 @@ contract SIP02 is GovernorBravoProposal {
true,
"USDT should be authorized"
);

assertEq(
vault.maxSupply(),
1_000_000e18,
"Max supply should be 1,000,000 USDC"
);
assertEq(
vault.totalSupplied(),
1_000e18,
"Total supplied should be 1000 USDC"
);
}
}
3 changes: 3 additions & 0 deletions src/exercises/03/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Overview

Make the contract upgradeable while preserving all previous functionality. Users can migrate to this contract via opt-in by removing their liquidity from the previous contract and depositing here.
50 changes: 28 additions & 22 deletions src/exercises/03/SIP04.sol → src/exercises/03/SIP03.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import {GovernorBravoProposal} from
import {Addresses} from
"@forge-proposal-simulator/addresses/Addresses.sol";

import {Vault04} from "src/exercises/04/Vault04.sol";
import {MockToken} from "@mocks/MockToken.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";
import {
ProxyAdmin,
TransparentUpgradeableProxy,
Expand All @@ -19,8 +16,11 @@ import {ERC1967Utils} from
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/// DO_RUN=false DO_BUILD=false DO_DEPLOY=true DO_SIMULATE=false DO_PRINT=false DO_VALIDATE=true forge script src/exercises/SIP04.sol:SIP04 -vvvv
contract SIP04 is GovernorBravoProposal {
import {Vault} from "src/exercises/03/Vault03.sol";
import {ForkSelector, ETHEREUM_FORK_ID} from "@test/utils/Forks.sol";

/// DO_RUN=false DO_BUILD=false DO_DEPLOY=true DO_SIMULATE=false DO_PRINT=false DO_VALIDATE=true forge script src/exercises/03/SIP03.sol:SIP03 -vvvv
contract SIP03 is GovernorBravoProposal {
using ForkSelector for uint256;

constructor() {
Expand All @@ -38,7 +38,7 @@ contract SIP04 is GovernorBravoProposal {
}

function name() public pure override returns (string memory) {
return "SIP-04 Upgrade";
return "SIP-03 Upgrade";
}

function description()
Expand All @@ -59,45 +59,45 @@ contract SIP04 is GovernorBravoProposal {
}

function deploy() public override {
if (!addresses.isAddressSet("PROXY_ADMIN")) {
ProxyAdmin proxyAdmin = new ProxyAdmin();
proxyAdmin.transferOwnership(
addresses.getAddress("COMPOUND_TIMELOCK_BRAVO")
);

addresses.addAddress("PROXY_ADMIN", address(proxyAdmin), true);
}

address vaultProxy;
if (!addresses.isAddressSet("V4_VAULT_IMPLEMENTATION")) {
address vaultImpl = address(new Vault04());
addresses.addAddress(
"V4_VAULT_IMPLEMENTATION", vaultImpl, true
);
if (!addresses.isAddressSet("V3_VAULT_IMPL")) {
address vaultImpl = address(new Vault());
addresses.addAddress("V3_VAULT_IMPL", vaultImpl, true);

address[] memory tokens = new address[](3);
tokens[0] = addresses.getAddress("USDC");
tokens[1] = addresses.getAddress("DAI");
tokens[2] = addresses.getAddress("USDT");

address owner = addresses.getAddress("COMPOUND_TIMELOCK_BRAVO");
address owner =
addresses.getAddress("COMPOUND_TIMELOCK_BRAVO");

// Generate calldata for initialize function of vault
bytes memory data = abi.encodeWithSignature(
"initialize(address[],address)", tokens, owner
);

/// proxy admin contract is created by the Transparent Upgradeable Proxy
vaultProxy = address(
new TransparentUpgradeableProxy(
vaultImpl, owner, data
)
);
addresses.addAddress("VAULT_PROXY", vaultProxy, true);

address proxyAdmin = address(
uint160(
uint256(
vm.load(vaultProxy, ERC1967Utils.ADMIN_SLOT)
)
)
);
addresses.addAddress("PROXY_ADMIN", proxyAdmin, true);
}
}

function validate() public view override {
Vault04 vault = Vault04(addresses.getAddress("VAULT_PROXY"));
Vault vault = Vault(addresses.getAddress("VAULT_PROXY"));

assertEq(
vault.authorizedToken(addresses.getAddress("USDC")),
Expand All @@ -120,5 +120,11 @@ contract SIP04 is GovernorBravoProposal {
vm.load(vaultProxy, ERC1967Utils.ADMIN_SLOT);

address proxyAdmin = address(uint160(uint256(adminSlot)));

assertEq(
ProxyAdmin(proxyAdmin).owner(),
addresses.getAddress("COMPOUND_TIMELOCK_BRAVO"),
"owner not set"
);
}
}
18 changes: 4 additions & 14 deletions src/exercises/04/Vault05.sol → src/exercises/03/Vault03.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,15 @@ import {IERC20Metadata} from
"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {SafeERC20} from
"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {OwnableUpgradeable} from
"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {VaultStoragePausable} from
"src/exercises/storage/VaultStoragePausable.sol";
import {VaultStorageOwnable} from
"src/exercises/storage/VaultStorageOwnable.sol";

/// @notice Add maxsupply to the vault and update getNormalizedAmount logic
/// TODO make pauseable
/// make totalSupplied offsets the same
/// inherit pausable to mess up the storage slot offsets
/// add governance proposal that deploys and ugprades the existing vault from
/// proposal 03
/// deploy Vault 03 to mainnet
/// add integration tests
contract Vault05 is VaultStoragePausable {
contract Vault is VaultStorageOwnable {
using SafeERC20 for IERC20;

/// @notice Deposit event
Expand Down Expand Up @@ -116,10 +109,7 @@ contract Vault05 is VaultStoragePausable {
/// @notice Deposit tokens into the vault
/// @param token The token to deposit, only authorized tokens allowed
/// @param amount The amount to deposit
function deposit(address token, uint256 amount)
external
whenNotPaused
{
function deposit(address token, uint256 amount) external {
require(authorizedToken[token], "Vault: token not authorized");

uint256 normalizedAmount = getNormalizedAmount(token, amount);
Expand Down
21 changes: 0 additions & 21 deletions src/exercises/03/Vault04Storage.sol

This file was deleted.

5 changes: 5 additions & 0 deletions src/exercises/04/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Overview

Make the contract pauseable, while preserving all previous functionality. Users should not be able to deposit when the contract is paused. Users should be able to withdraw their liquidity when the contract is paused. Only the owner can pause and unpause the contract.

Then upgrade the existing contract's implementation to this new contract. This migration is forced, and users not wishing to stay for this new contract upgrade must withdraw their liquidity.
Loading

0 comments on commit aecfda8

Please sign in to comment.