Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renaming #80

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The system is comprised of several layers:

- Core Allocation System (*green above*):
- Smart contracts that can be considered a part of the Maker Core Protocol, and are immutable and present in all Allocators.
- Their main role is to mint NST (New Stable Token) and hold it (possibly with other tokens) in the `AllocatorBuffer`.
- Their main role is to mint USDS (New Stable Token) and hold it (possibly with other tokens) in the `AllocatorBuffer`.
- Deployment Funnels (*blue above*):
- Contracts that pull funds from the `AllocatorBuffer`.
- The funds can be swapped and/or deployed into AMM pools or specific conduits.
Expand All @@ -33,7 +33,7 @@ The allocation system includes several actor types:

- Pause Proxy:
- Performs actions through spells with governance delay.
- In charge of setting up the core components and the NST minting instant access modules (DC-IAMs).
- In charge of setting up the core components and the USDS minting instant access modules (DC-IAMs).
- Ward of the singleton contracts (e.g RWA conduits, Coinbase Custody, `AllocatorRoles`).
- AllocatorDAO Proxy:
- Performs actions through a sub-spell with governance delay.
Expand All @@ -46,7 +46,7 @@ The allocation system includes several actor types:
- An optional actor which is whitelisted through the `AllocatorRoles` contract to perform specified actions on the `AllocatorVault`, funnels and conduits.
- Will typically be a facilitator multisig or an automation contract controlled by one (e.g `StableSwapper`, `StableDepositorUniV3`).
- Keeper:
- An optional actor which can be set up to trigger the automation contracts in case repetitive actions are needed (such as swapping NST to USDC every time interval).
- An optional actor which can be set up to trigger the automation contracts in case repetitive actions are needed (such as swapping USDS to USDC every time interval).

![Untitled (1)](https://github.com/makerdao/dss-allocator/assets/130549691/c677928b-32f4-4000-b6ed-e3798caa9c5c)

Expand All @@ -61,15 +61,15 @@ Each AllocatorDAO has a unique `ilk` (collateral type) with one VAT vault set up

Single contract per `ilk`, which operators can use to:

- Mint (`draw`) NST from the vault to the AllocatorBuffer.
- Repay (`wipe`) NST from the AllocatorBuffer.
- Mint (`draw`) USDS from the vault to the AllocatorBuffer.
- Repay (`wipe`) USDS from the AllocatorBuffer.

### AllocatorBuffer

A simple contract for the AllocatorDAO to hold funds in.

- Supports approving contracts to `transferFrom` it.
- Note that although the `AllocatorVault` pushes and pulls NST to/from the `AllocatorBuffer`, it can manage other tokens as well.
- Note that although the `AllocatorVault` pushes and pulls USDS to/from the `AllocatorBuffer`, it can manage other tokens as well.

### AllocatorRoles

Expand Down Expand Up @@ -112,7 +112,7 @@ An automation contract sample, which can be used by the AllocatorDAOs to `draw`

### StableSwapper

An automation contract, which can be used by the AllocatorDAOs to set up recurring swaps of stable tokens (e.g NST to USDC).
An automation contract, which can be used by the AllocatorDAOs to set up recurring swaps of stable tokens (e.g USDS to USDC).

- In order to use it, the AllocatorDAO should list it as an operator of its `Swapper` primitive in the `AllocatorRoles` contract.
- The `Swapper` primitive will rate-limit the automation contract.
Expand Down
16 changes: 8 additions & 8 deletions certora/AllocatorVault.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
"src/AllocatorRoles.sol",
"test/mocks/VatMock.sol",
"test/mocks/JugMock.sol",
"test/mocks/NstJoinMock.sol",
"test/mocks/NstMock.sol"
"test/mocks/UsdsJoinMock.sol",
"test/mocks/UsdsMock.sol"
],
"link": [
"AllocatorVault:roles=AllocatorRoles",
"AllocatorVault:vat=VatMock",
"AllocatorVault:jug=JugMock",
"AllocatorVault:nstJoin=NstJoinMock",
"AllocatorVault:nst=NstMock",
"AllocatorVault:usdsJoin=UsdsJoinMock",
"AllocatorVault:usds=UsdsMock",
"JugMock:vat=VatMock",
"NstJoinMock:vat=VatMock",
"NstJoinMock:nst=NstMock"
"UsdsJoinMock:vat=VatMock",
"UsdsJoinMock:usds=UsdsMock"
],
"rule_sanity": "basic",
"solc": "solc-0.8.16",
Expand All @@ -24,8 +24,8 @@
"AllocatorRoles": "200",
"VatMock": "0",
"JugMock": "0",
"NstJoinMock": "0",
"NstMock": "0"
"UsdsJoinMock": "0",
"UsdsMock": "0"
},
"verify": "AllocatorVault:certora/AllocatorVault.spec",
"parametric_contracts": [
Expand Down
76 changes: 38 additions & 38 deletions certora/AllocatorVault.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using AllocatorRoles as roles;
using VatMock as vat;
using JugMock as jug;
using NstJoinMock as nstJoin;
using NstMock as nst;
using UsdsJoinMock as usdsJoin;
using UsdsMock as usds;

methods {
function ilk() external returns (bytes32) envfree;
Expand All @@ -19,9 +19,9 @@ methods {
function vat.rate() external returns (uint256) envfree;
function jug.duty() external returns (uint256) envfree;
function jug.rho() external returns (uint256) envfree;
function nst.allowance(address, address) external returns (uint256) envfree;
function nst.balanceOf(address) external returns (uint256) envfree;
function nst.totalSupply() external returns (uint256) envfree;
function usds.allowance(address, address) external returns (uint256) envfree;
function usds.balanceOf(address) external returns (uint256) envfree;
function usds.totalSupply() external returns (uint256) envfree;
}

definition WAD() returns mathint = 10^18;
Expand Down Expand Up @@ -145,9 +145,9 @@ rule file_revert(bytes32 what, address data) {
rule draw(uint256 wad) {
env e;

mathint nstTotalSupplyBefore = nst.totalSupply();
mathint nstBalanceOfBufferBefore = nst.balanceOf(buffer());
require nstBalanceOfBufferBefore <= nstTotalSupplyBefore;
mathint usdsTotalSupplyBefore = usds.totalSupply();
mathint usdsBalanceOfBufferBefore = usds.balanceOf(buffer());
require usdsBalanceOfBufferBefore <= usdsTotalSupplyBefore;
mathint vatInkVaultBefore; mathint vatArtVaultBefore;
vatInkVaultBefore, vatArtVaultBefore = vat.urns(ilk(), currentContract);
mathint rate = vat.rate() + (jug.duty() - RAY()) * (e.block.timestamp - jug.rho());
Expand All @@ -156,15 +156,15 @@ rule draw(uint256 wad) {

draw(e, wad);

mathint nstTotalSupplyAfter = nst.totalSupply();
mathint nstBalanceOfBufferAfter = nst.balanceOf(buffer());
mathint usdsTotalSupplyAfter = usds.totalSupply();
mathint usdsBalanceOfBufferAfter = usds.balanceOf(buffer());
mathint vatInkVaultAfter; mathint vatArtVaultAfter;
vatInkVaultAfter, vatArtVaultAfter = vat.urns(ilk(), currentContract);

assert vatInkVaultAfter == vatInkVaultBefore, "draw did not keep vat.urns(ilk,vault).ink unchanged";
assert vatArtVaultAfter == vatArtVaultBefore + dart, "draw did not increase vat.urns(ilk,vault).art by dart";
assert nstBalanceOfBufferAfter == nstBalanceOfBufferBefore + wad, "draw did not increase nst.balanceOf(buffer) by wad";
assert nstTotalSupplyAfter == nstTotalSupplyBefore + wad, "draw did not increase nst.totalSupply() by wad";
assert usdsBalanceOfBufferAfter == usdsBalanceOfBufferBefore + wad, "draw did not increase usds.balanceOf(buffer) by wad";
assert usdsTotalSupplyAfter == usdsTotalSupplyBefore + wad, "draw did not increase usds.totalSupply() by wad";
}

// Verify revert rules on draw
Expand All @@ -173,9 +173,9 @@ rule draw_revert(uint256 wad) {

bool canCall = roles.canCall(ilk(), e.msg.sender, currentContract, to_bytes4(0x3b304147));
mathint wardsSender = wards(e.msg.sender);
mathint nstTotalSupply = nst.totalSupply();
mathint nstBalanceOfBuffer = nst.balanceOf(buffer());
require nstBalanceOfBuffer <= nstTotalSupply;
mathint usdsTotalSupply = usds.totalSupply();
mathint usdsBalanceOfBuffer = usds.balanceOf(buffer());
require usdsBalanceOfBuffer <= usdsTotalSupply;
mathint vatInkVault; mathint vatArtVault;
vatInkVault, vatArtVault = vat.urns(ilk(), currentContract);
mathint duty = jug.duty();
Expand All @@ -186,8 +186,8 @@ rule draw_revert(uint256 wad) {
require rate > 0 && rate <= max_int256();
mathint dart = divUp(wad * RAY(), rate);
mathint vatDaiVault = vat.dai(currentContract);
mathint vatCanVaultNstJoin = vat.can(currentContract, nstJoin);
mathint vatDaiNstJoin = vat.dai(nstJoin);
mathint vatCanVaultUsdsJoin = vat.can(currentContract, usdsJoin);
mathint vatDaiUsdsJoin = vat.dai(usdsJoin);

draw@withrevert(e, wad);

Expand All @@ -198,9 +198,9 @@ rule draw_revert(uint256 wad) {
bool revert5 = vatArtVault + dart > max_uint256;
bool revert6 = rate * dart > max_int256();
bool revert7 = vatDaiVault + rate * dart > max_uint256;
bool revert8 = vatCanVaultNstJoin != 1;
bool revert9 = vatDaiNstJoin + wad * RAY() > max_uint256;
bool revert10 = nstTotalSupply + wad > max_uint256;
bool revert8 = vatCanVaultUsdsJoin != 1;
bool revert9 = vatDaiUsdsJoin + wad * RAY() > max_uint256;
bool revert10 = usdsTotalSupply + wad > max_uint256;

assert lastReverted <=> revert1 || revert2 || revert3 ||
revert4 || revert5 || revert6 ||
Expand All @@ -212,9 +212,9 @@ rule draw_revert(uint256 wad) {
rule wipe(uint256 wad) {
env e;

mathint nstTotalSupplyBefore = nst.totalSupply();
mathint nstBalanceOfBufferBefore = nst.balanceOf(buffer());
require nstBalanceOfBufferBefore <= nstTotalSupplyBefore;
mathint usdsTotalSupplyBefore = usds.totalSupply();
mathint usdsBalanceOfBufferBefore = usds.balanceOf(buffer());
require usdsBalanceOfBufferBefore <= usdsTotalSupplyBefore;
mathint vatInkVaultBefore; mathint vatArtVaultBefore;
vatInkVaultBefore, vatArtVaultBefore = vat.urns(ilk(), currentContract);
mathint rate = vat.rate() + (jug.duty() - RAY()) * (e.block.timestamp - jug.rho());
Expand All @@ -223,15 +223,15 @@ rule wipe(uint256 wad) {

wipe(e, wad);

mathint nstTotalSupplyAfter = nst.totalSupply();
mathint nstBalanceOfBufferAfter = nst.balanceOf(buffer());
mathint usdsTotalSupplyAfter = usds.totalSupply();
mathint usdsBalanceOfBufferAfter = usds.balanceOf(buffer());
mathint vatInkVaultAfter; mathint vatArtVaultAfter;
vatInkVaultAfter, vatArtVaultAfter = vat.urns(ilk(), currentContract);

assert vatInkVaultAfter == vatInkVaultBefore, "wipe did not keep vat.urns(ilk,vault).ink unchanged";
assert vatArtVaultAfter == vatArtVaultBefore - dart, "wipe did not decrease vat.urns(ilk,vault).art by dart";
assert nstBalanceOfBufferAfter == nstBalanceOfBufferBefore - wad, "wipe did not decrease nst.balanceOf(buffer) by wad";
assert nstTotalSupplyAfter == nstTotalSupplyBefore - wad, "wipe did not decrease nst.totalSupply() by wad";
assert usdsBalanceOfBufferAfter == usdsBalanceOfBufferBefore - wad, "wipe did not decrease usds.balanceOf(buffer) by wad";
assert usdsTotalSupplyAfter == usdsTotalSupplyBefore - wad, "wipe did not decrease usds.totalSupply() by wad";
}

// Verify revert rules on wipe
Expand All @@ -240,14 +240,14 @@ rule wipe_revert(uint256 wad) {

bool canCall = roles.canCall(ilk(), e.msg.sender, currentContract, to_bytes4(0xb38a1620));
mathint wardsSender = wards(e.msg.sender);
mathint nstTotalSupply = nst.totalSupply();
mathint usdsTotalSupply = usds.totalSupply();
address buffer = buffer();
require buffer != currentContract;
mathint nstBalanceOfBuffer = nst.balanceOf(buffer);
mathint nstBalanceOfVault = nst.balanceOf(currentContract);
require nstBalanceOfBuffer + nstBalanceOfVault <= nstTotalSupply;
mathint nstAllowanceBufferVault = nst.allowance(buffer, currentContract);
mathint nstAllowanceVaultNstJoin = nst.allowance(currentContract, nstJoin);
mathint usdsBalanceOfBuffer = usds.balanceOf(buffer);
mathint usdsBalanceOfVault = usds.balanceOf(currentContract);
require usdsBalanceOfBuffer + usdsBalanceOfVault <= usdsTotalSupply;
mathint usdsAllowanceBufferVault = usds.allowance(buffer, currentContract);
mathint usdsAllowanceVaultUsdsJoin = usds.allowance(currentContract, usdsJoin);
mathint vatInkVault; mathint vatArtVault;
vatInkVault, vatArtVault = vat.urns(ilk(), currentContract);
mathint duty = jug.duty();
Expand All @@ -258,18 +258,18 @@ rule wipe_revert(uint256 wad) {
require rate > 0 && rate <= max_int256();
mathint dart = wad * RAY() / rate;
mathint vatDaiVault = vat.dai(currentContract);
mathint vatDaiNstJoin = vat.dai(nstJoin);
mathint vatDaiUsdsJoin = vat.dai(usdsJoin);

wipe@withrevert(e, wad);

bool revert1 = e.msg.value > 0;
bool revert2 = !canCall && wardsSender != 1;
bool revert3 = nstBalanceOfBuffer < to_mathint(wad);
bool revert4 = nstAllowanceBufferVault < to_mathint(wad);
bool revert3 = usdsBalanceOfBuffer < to_mathint(wad);
bool revert4 = usdsAllowanceBufferVault < to_mathint(wad);
bool revert5 = wad * RAY() > max_uint256;
bool revert6 = nstAllowanceVaultNstJoin < to_mathint(wad);
bool revert6 = usdsAllowanceVaultUsdsJoin < to_mathint(wad);
bool revert7 = vatArtVault < dart;
bool revert8 = vatDaiNstJoin < wad * RAY();
bool revert8 = vatDaiUsdsJoin < wad * RAY();
bool revert9 = vatDaiVault + wad * RAY() > max_uint256;
bool revert10 = rate * dart > max_int256();

Expand Down
4 changes: 2 additions & 2 deletions deploy/AllocatorDeploy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ library AllocatorDeploy {
address owner,
address roles,
bytes32 ilk,
address nstJoin
address usdsJoin
) internal returns (AllocatorIlkInstance memory ilkInstance) {
address _buffer = address(new AllocatorBuffer());
ScriptTools.switchOwner(_buffer, deployer, owner);
ilkInstance.buffer = _buffer;

address _vault = address(new AllocatorVault(roles, _buffer, ilk, nstJoin));
address _vault = address(new AllocatorVault(roles, _buffer, ilk, usdsJoin));
ScriptTools.switchOwner(_vault, deployer, owner);
ilkInstance.vault = _vault;

Expand Down
6 changes: 3 additions & 3 deletions deploy/AllocatorInit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ interface VaultLike {
function roles() external view returns (address);
function buffer() external view returns (address);
function vat() external view returns (address);
function nst() external view returns (address);
function usds() external view returns (address);
function file(bytes32, address) external;
}

Expand Down Expand Up @@ -107,7 +107,7 @@ library AllocatorInit {
require(VaultLike(ilkInstance.vault).roles() == sharedInstance.roles, "AllocatorInit/vault-roles-mismatch");
require(VaultLike(ilkInstance.vault).buffer() == ilkInstance.buffer, "AllocatorInit/vault-buffer-mismatch");
require(VaultLike(ilkInstance.vault).vat() == address(dss.vat), "AllocatorInit/vault-vat-mismatch");
// Once nstJoin is in the chainlog and adapted to dss-test should also check against it
// Once usdsJoin is in the chainlog and adapted to dss-test should also check against it

// Onboard the ilk
dss.vat.init(ilk);
Expand All @@ -134,7 +134,7 @@ library AllocatorInit {
VaultLike(ilkInstance.vault).file("jug", address(dss.jug));

// Allow vault to pull funds from the buffer
BufferLike(ilkInstance.buffer).approve(VaultLike(ilkInstance.vault).nst(), ilkInstance.vault, type(uint256).max);
BufferLike(ilkInstance.buffer).approve(VaultLike(ilkInstance.vault).usds(), ilkInstance.vault, type(uint256).max);

// Set the allocator proxy as the ilk admin instead of the Pause Proxy
RolesLike(sharedInstance.roles).setIlkAdmin(ilk, cfg.allocatorProxy);
Expand Down
34 changes: 17 additions & 17 deletions src/AllocatorVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ interface GemLike {
function transferFrom(address, address, uint256) external;
}

interface NstJoinLike {
function nst() external view returns (GemLike);
interface UsdsJoinLike {
function usds() external view returns (GemLike);
function vat() external view returns (VatLike);
function exit(address, uint256) external;
function join(address, uint256) external;
Expand All @@ -55,12 +55,12 @@ contract AllocatorVault {

// --- immutables ---

RolesLike immutable public roles;
address immutable public buffer;
VatLike immutable public vat;
bytes32 immutable public ilk;
NstJoinLike immutable public nstJoin;
GemLike immutable public nst;
RolesLike immutable public roles;
address immutable public buffer;
VatLike immutable public vat;
bytes32 immutable public ilk;
UsdsJoinLike immutable public usdsJoin;
GemLike immutable public usds;

// --- events ---

Expand All @@ -80,18 +80,18 @@ contract AllocatorVault {

// --- constructor ---

constructor(address roles_, address buffer_, bytes32 ilk_, address nstJoin_) {
constructor(address roles_, address buffer_, bytes32 ilk_, address usdsJoin_) {
roles = RolesLike(roles_);

buffer = buffer_;
ilk = ilk_;
nstJoin = NstJoinLike(nstJoin_);
usdsJoin = UsdsJoinLike(usdsJoin_);

vat = nstJoin.vat();
nst = nstJoin.nst();
vat = usdsJoin.vat();
usds = usdsJoin.usds();

vat.hope(nstJoin_);
nst.approve(nstJoin_, type(uint256).max);
vat.hope(usdsJoin_);
usds.approve(usdsJoin_, type(uint256).max);

wards[msg.sender] = 1;
emit Rely(msg.sender);
Expand Down Expand Up @@ -132,13 +132,13 @@ contract AllocatorVault {
uint256 dart = _divup(wad * RAY, rate);
require(dart <= uint256(type(int256).max), "AllocatorVault/overflow");
vat.frob(ilk, address(this), address(0), address(this), 0, int256(dart));
nstJoin.exit(buffer, wad);
usdsJoin.exit(buffer, wad);
emit Draw(msg.sender, wad);
}

function wipe(uint256 wad) external auth {
nst.transferFrom(buffer, address(this), wad);
nstJoin.join(address(this), wad);
usds.transferFrom(buffer, address(this), wad);
usdsJoin.join(address(this), wad);
uint256 rate = jug.drip(ilk);
uint256 dart = wad * RAY / rate;
require(dart <= uint256(type(int256).max), "AllocatorVault/overflow");
Expand Down
Loading
Loading