Skip to content
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
65 changes: 27 additions & 38 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ COLLATERAL_ADDRESS_0="0x5555555555555555555555555555555555555555"
COLLATERAL_NAME_0="Wrapped HYPE"
COLLATERAL_SYMBOL_0="WHYPE"
COLLATERAL_DECIMALS_0=18
COLLATERAL_NAME_1="Wrapped Bitcoin"
COLLATERAL_SYMBOL_1="WBTC"
COLLATERAL_NAME_1="Unit Bitcoin"
COLLATERAL_SYMBOL_1="UBTC"
COLLATERAL_DECIMALS_1=8

# USD Tokens
USD_TOKEN_LENGTH=2
USD_NAME_0="USD Coin"
USD_SYMBOL_0="USDC"
USD_TOKEN_LENGTH=3
USD_NAME_0="USD₮0"
USD_SYMBOL_0="USD₮0"
USD_DECIMALS_0=6
USD_NAME_1="Tether USD"
USD_SYMBOL_1="USDT"
USD_NAME_1="USDC"
USD_SYMBOL_1="USDC"
USD_DECIMALS_1=6
USD_NAME_2="USDH"
USD_SYMBOL_2="USDH"
USD_DECIMALS_2=6

# USDX
USDX_NAME="USDX"
Expand All @@ -50,50 +53,36 @@ CONSOL_NAME="Buttonwood Consol"
CONSOL_SYMBOL="CONSOL"
CONSOL_DECIMALS_OFFSET=8

# Consol Maximum Caps
CONSOL_USDX_MAXIMUM_CAP=10000000000000000000000

# General Manager
PENALTY_RATE=200
PENALTY_RATE=2000
REFINANCE_RATE=300
CONVERSION_PREMIUM_RATE=5000 # 50% Price increase before conversion triggered
PRICE_SPREAD=100 # 1% spread on the price oracle
INSURANCE_FUND=0xfD99d2d103b09F95c3dFc458F57178bF0CD587B1
SUPPORTED_PERIOD_TERMS_LENGTH=2
SUPPORTED_PERIOD_TERMS_LENGTH=1
SUPPORTED_PERIOD_TERM_0=36
SUPPORTED_PERIOD_TERM_1=60
MINIMUM_CAP_0=100000000000000000000
MINIMUM_CAP_1=100000000000000000000
MAXIMUM_CAP_0=1000000000000000000000000
MAXIMUM_CAP_1=1000000000000000000000000
MINIMUM_CAP_0=1000000000000000000
MINIMUM_CAP_1=1000000000000000000
MAXIMUM_CAP_0=1000000000000000000000
MAXIMUM_CAP_1=1000000000000000000000

# NFT
NFT_NAME="Buttonwood Mortgage"
NFT_SYMBOL="BMT"
NFT_NAME="Buttonwood Position"
NFT_SYMBOL="BPT"

# Initial Origination Pool Configs
INITIAL_ORIGINATION_POOL_CONFIG_LENGTH=3
INITIAL_ORIGINATION_POOL_CONFIG_LENGTH=1
## First Origination Pool 0%
INITIAL_ORIGINATION_POOL_0_NAME_PREFIX="Default Origination Pool #1"
INITIAL_ORIGINATION_POOL_0_SYMBOL_PREFIX="DOP1"
INITIAL_ORIGINATION_POOL_0_DEPOSIT_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_0_DEPLOY_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_0_DEFAULT_POOL_LIMIT=100000000000000000000000 # 100k limit
INITIAL_ORIGINATION_POOL_0_NAME_PREFIX="0% Origination Pool"
INITIAL_ORIGINATION_POOL_0_SYMBOL_PREFIX="0% OP"
INITIAL_ORIGINATION_POOL_0_DEPOSIT_PHASE_DURATION=86400 # 1 Day
INITIAL_ORIGINATION_POOL_0_DEPLOY_PHASE_DURATION=172800 # 2 Days
INITIAL_ORIGINATION_POOL_0_DEFAULT_POOL_LIMIT=10000000000000000000000 # 10k limit
INITIAL_ORIGINATION_POOL_0_POOL_LIMIT_GROWTH_RATE_BPS=500 # 5% growth rate if used up
INITIAL_ORIGINATION_POOL_0_POOL_MULTIPLIER_BPS=0 # 0% multiplier
## Second Origination Pool 1%
INITIAL_ORIGINATION_POOL_1_NAME_PREFIX="Default Origination Pool #2"
INITIAL_ORIGINATION_POOL_1_SYMBOL_PREFIX="DOP2"
INITIAL_ORIGINATION_POOL_1_DEPOSIT_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_1_DEPLOY_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_1_DEFAULT_POOL_LIMIT=100000000000000000000000 # 100k limit
INITIAL_ORIGINATION_POOL_1_POOL_LIMIT_GROWTH_RATE_BPS=500 # 5% growth rate if used up
INITIAL_ORIGINATION_POOL_1_POOL_MULTIPLIER_BPS=100 # 1% multiplier
## Third Origination Pool 2%
INITIAL_ORIGINATION_POOL_2_NAME_PREFIX="Default Origination Pool #3"
INITIAL_ORIGINATION_POOL_2_SYMBOL_PREFIX="DOP3"
INITIAL_ORIGINATION_POOL_2_DEPOSIT_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_2_DEPLOY_PHASE_DURATION=604800
INITIAL_ORIGINATION_POOL_2_DEFAULT_POOL_LIMIT=100000000000000000000000 # 100k limit
INITIAL_ORIGINATION_POOL_2_POOL_LIMIT_GROWTH_RATE_BPS=500 # 5% growth rate if used up
INITIAL_ORIGINATION_POOL_2_POOL_MULTIPLIER_BPS=200 # 2% multiplier

# Price Oracles
STATIC_INTEREST_RATE_ORACLE_BASE=400 # 5% for paymentPlan, 6% for no paymentPlan
Expand Down
40 changes: 21 additions & 19 deletions addresses/addresses-998.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,36 @@
"collateralAddresses": [
"0x5555555555555555555555555555555555555555"
],
"consolAddress": "0xa6de291b20532E2A1D842B3d2F3Ac81C8a24dc58",
"consolAddress": "0x9e7530745aD90781a05702bE77A8E0D13C2edc04",
"conversionQueues": [
"0xd0eF45d632d4de20eda73f48df5cC4d6b5350B51"
"0xeD23dF861c5E5718FEA856BB891E17efd281F1Ed"
],
"forfeitedAssetsPoolAddress": "0xE95dD3d5d5170FA7D386c3a9b3414bd2e47C31C2",
"forfeitedAssetsQueue": "0xE32eE27c1716451A7033c0cD1B4b165493F86b44",
"generalManagerAddress": "0x09Aba0Efe808eEc0d7829F9c5dB53d5756F90940",
"interestRateOracleAddress": "0x80Ec0B4a5Fd5A2Bb614dAedf804e45a5AdCC2211",
"loanManagerAddress": "0x8d69266F253d1A5e9c1E6442e797233E55C8825e",
"mortgageNFTAddress": "0xA7CeBaCc5e759633389a46CC27E3f8196c738832",
"forfeitedAssetsPoolAddress": "0x47d77EB2Ec92a62Ee911683A9399d5bd31B83542",
"forfeitedAssetsQueue": "0xb21805F2E99EF36fa60FA1D630edBd92B3C4a87d",
"generalManagerAddress": "0xb96c3d0e9Be0580E3F00a81e69B868F4E9fdBbD7",
"interestRateOracleAddress": "0xB686AD9B5F6E0055D5089B4E4C1A4a911eDd34C6",
"loanManagerAddress": "0xCa306A74349B957081f17030a23a12FA4317C23B",
"mortgageNFTAddress": "0x0dfC09f870A526CebF9810272B0CEE2De35B6eCe",
"nativeWrapper": "0x5555555555555555555555555555555555555555",
"nftMetadataGeneratorAddress": "0x995ec0b3a0A9F57E8120A560e999F252792d97a3",
"orderPoolAddress": "0xdC2836C08A176F9164a61E9d55EC573dE72D736E",
"originationPoolSchedulerAddress": "0xc619751aF552eb462E057A104E65027eB1739f57",
"nftMetadataGeneratorAddress": "0x065e0bD3EdBEa143Ba05F10Ca9e097C31aB5816b",
"orderPoolAddress": "0xBAE41Be1aF566bA80390B0b695Ac79900C0AdbAb",
"originationPoolSchedulerAddress": "0x6BEC3983ac51cc5CEeB5c3Abdaa44e09B41763b3",
"priceOracles": [
"0xAA3eFEDA23A8BCF341B2512E1A51f641D21Fe972"
"0xA498F054a75b859d96c2e9E7290Fe29FEF5586Fc"
],
"processor": "0x26114766Dd74A9c2D167B3d75Da9eeD5B156A94A",
"pythAddress": "0x6F1D6e894e4ddCC2dCcb71753A5bA9e11b1F77b1",
"processor": "0x90790538e083245fe69c761E75DBa58fE6Ce9A5d",
"pythAddress": "0xc12dFA84277961245D5BEaCFb36491CfA8Ec32A8",
"subConsolAddresses": [
"0x6C0Adc34e32f53300EaB6E038D25dA55d7D5AD6B"
"0x97E5977B2aFd14a4c91E6D7F2D686f86762873E4"
],
"usdAddresses": [
"0xA8BaDD004FA44C42964cA280A239C13e7d887021"
"0x06EF296be8E377F016EbD7a271A3566A6dBfdD23",
"0x3F81B0daB4775C69aD7dE7333E0224a5E9A21De4",
"0x5d23A97AcC7576F2cfB7122de1325BC4841A1f7A"
],
"usdxAddress": "0x7A53BC73f834A63f4a57D2D862F5eD58630e6266",
"usdxQueue": "0x1530530632e555bb0ba93A57fFe9Fa417bc6992F",
"usdxAddress": "0xf28A7DdE266237428fa1FA5aFa700eF40DBd3589",
"usdxQueue": "0x34dBD3E75fB33403C7b2434b759EC510e9da2262",
"yieldStrategies": [
"0x186fd23C5BC4Ab5855964Fdfdbe2D0A8dF291F46"
"0x5b4834644f0A9557047D8f68A172ef48dEEc0672"
]
}
1,986 changes: 1,986 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759846074108.json

Large diffs are not rendered by default.

2,783 changes: 2,783 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759846322246.json

Large diffs are not rendered by default.

2,783 changes: 2,783 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759846802223.json

Large diffs are not rendered by default.

1,986 changes: 1,986 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759846912524.json

Large diffs are not rendered by default.

2,294 changes: 2,294 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759847042558.json

Large diffs are not rendered by default.

4,859 changes: 4,859 additions & 0 deletions broadcast/DeployAll.s.sol/998/run-1759849082607.json

Large diffs are not rendered by default.

3,729 changes: 2,259 additions & 1,470 deletions broadcast/DeployAll.s.sol/998/run-latest.json

Large diffs are not rendered by default.

1,614 changes: 1,614 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759854130981.json

Large diffs are not rendered by default.

1,616 changes: 1,616 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759854215647.json

Large diffs are not rendered by default.

3,971 changes: 3,971 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759854959893.json

Large diffs are not rendered by default.

1,338 changes: 1,338 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759928638501.json

Large diffs are not rendered by default.

1,348 changes: 1,348 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759928845208.json

Large diffs are not rendered by default.

3,305 changes: 3,305 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-1759929421599.json

Large diffs are not rendered by default.

3,305 changes: 3,305 additions & 0 deletions broadcast/DeployAll.s.sol/999/run-latest.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fs_permissions = [
{ access = "read-write", path = "./addresses/tests/"},
{ access = "read-write", path = "./addresses/addresses-31337.json"},
{ access = "read-write", path = "./addresses/addresses-998.json"},
{ access = "read-write", path = "./addresses/addresses-999.json"},
{ access = "read", path = "./script/artifacts/WHYPE9.json"}
]

Expand Down
4 changes: 2 additions & 2 deletions script/BaseScript.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ contract BaseScript is Script {

function setUp() public virtual {
deployerAddress = vm.envAddress("DEPLOYER_ADDRESS");
deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY"); // Disable for production
getAdmins();
isTest = vm.envBool("IS_TEST");
isTestnet = vm.envBool("IS_TESTNET");

require(deployerAddress == vm.addr(deployerPrivateKey), "Deployer address and private key do not match");
require(deployerAddress == vm.addr(deployerPrivateKey), "Deployer address and private key do not match"); // Disable for production
}

function getAdmins() public {
Expand Down
6 changes: 4 additions & 2 deletions script/DeployAll.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ contract DeployAll is DeployOriginationScheduler, DeployOrderPool, DeployLoanMan
// Deploy SubConsols
deploySubConsols();
// Deploy YieldStrategies
deployYieldStrategies();
deployYieldStrategies(); // Disabled for production
// Deploy Consol
deployConsol();
// Get or create the pyth oracle
Expand All @@ -39,7 +39,7 @@ contract DeployAll is DeployOriginationScheduler, DeployOrderPool, DeployLoanMan
// Deploy PriceOracles that read from the PythOracle
deployPriceOracles();
// Deploy NFTMetadataGenerator
deployNFTMetadataGenerator();
deployNFTMetadataGenerator(); // Disabled for production
// Deploy GeneralManager
deployGeneralManager();
// Deploy Processor
Expand All @@ -58,6 +58,8 @@ contract DeployAll is DeployOriginationScheduler, DeployOrderPool, DeployLoanMan
transferOriginationPoolSchedulerAdminRole();
// Deploy LoanManager
deployLoanManager();
// Set the Consol Usdx Maximum Cap
// setConsolUsdxMaximumCap(); // Enable for production
// Grant admin/withdraw roles and renounce on Consol
consolGrantRolesAndRenounce(
address(loanManager), address(generalManager), usdxQueue, forfeitedAssetsQueue, conversionQueues
Expand Down
7 changes: 6 additions & 1 deletion script/DeployConsol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ contract DeployConsol is DeployUSDX, DeployForfeitedAssetsPool, DeploySubConsols
consol.addSupportedToken(address(usdx));
}

function setConsolUsdxMaximumCap() public {
uint256 consolUsdxMaximumCap = vm.envUint("CONSOL_USDX_MAXIMUM_CAP");
Consol(address(consol)).setMaximumCap(address(usdx), consolUsdxMaximumCap);
}

function logConsol(string memory objectKey) public returns (string memory json) {
json = vm.serializeAddress(objectKey, "consolAddress", address(consol));
}
Expand Down Expand Up @@ -76,7 +81,7 @@ contract DeployConsol is DeployUSDX, DeployForfeitedAssetsPool, DeploySubConsols
// Grant IGNORE_CAP_ROLE to the General Manager
Consol(address(consol)).grantRole(Roles.IGNORE_CAP_ROLE, address(generalManager));

// Renounce roles
// Renounce roles // Disable for production
Consol(address(consol)).renounceRole(Roles.SUPPORTED_TOKEN_ROLE, deployerAddress);
Consol(address(consol)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}
Expand Down
2 changes: 1 addition & 1 deletion script/DeployForfeitedAssetsPool.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ contract DeployForfeitedAssetsPool is CollateralSetup {
// Grant depositor role to loan manager
ForfeitedAssetsPool(address(forfeitedAssetsPool)).grantRole(Roles.DEPOSITOR_ROLE, loanManager);

// Renounce admin role
// Renounce admin role // Disable for production
ForfeitedAssetsPool(address(forfeitedAssetsPool)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}
}
2 changes: 1 addition & 1 deletion script/DeployGeneralManager.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ contract DeployGeneralManager is DeployPriceOracles, DeployConsol {
GeneralManager(address(generalManager)).grantRole(Roles.DEFAULT_ADMIN_ROLE, admins[i]);
}

// Renounce the admin role from the broadcaster
// Renounce the admin role from the broadcaster // Disable for production
GeneralManager(address(generalManager)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}

Expand Down
2 changes: 1 addition & 1 deletion script/DeployOrderPool.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ contract DeployOrderPool is DeployGeneralManager {
IAccessControl(address(orderPool)).grantRole(Roles.FULFILLMENT_ROLE, deployerAddress);
}

// Renounce admin role
// Renounce admin role // Disable for production
IAccessControl(address(orderPool)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}

Expand Down
29 changes: 15 additions & 14 deletions script/DeployOriginationScheduler.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,20 @@ contract DeployOriginationScheduler is DeployGeneralManager {
uint16 poolMultiplierBps =
uint16(vm.envUint(string.concat("INITIAL_ORIGINATION_POOL_", vm.toString(i), "_POOL_MULTIPLIER_BPS")));

OriginationPoolScheduler(address(originationPoolScheduler)).addConfig(
OriginationPoolConfig({
namePrefix: namePrefix,
symbolPrefix: symbolPrefix,
consol: address(consol),
usdx: address(usdx),
depositPhaseDuration: depositPhaseDuration,
deployPhaseDuration: deployPhaseDuration,
defaultPoolLimit: defaultPoolLimit,
poolLimitGrowthRateBps: poolLimitGrowthRateBps,
poolMultiplierBps: poolMultiplierBps
})
);
OriginationPoolScheduler(address(originationPoolScheduler))
.addConfig(
OriginationPoolConfig({
namePrefix: namePrefix,
symbolPrefix: symbolPrefix,
consol: address(consol),
usdx: address(usdx),
depositPhaseDuration: depositPhaseDuration,
deployPhaseDuration: deployPhaseDuration,
defaultPoolLimit: defaultPoolLimit,
poolLimitGrowthRateBps: poolLimitGrowthRateBps,
poolMultiplierBps: poolMultiplierBps
})
);
}
}

Expand All @@ -75,7 +76,7 @@ contract DeployOriginationScheduler is DeployGeneralManager {
OriginationPoolScheduler(address(originationPoolScheduler)).grantRole(Roles.DEFAULT_ADMIN_ROLE, admins[i]);
}

// Renounce the admin role from the deployer
// Renounce the admin role from the deployer // Disable for production
OriginationPoolScheduler(address(originationPoolScheduler)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}

Expand Down
6 changes: 3 additions & 3 deletions script/DeployQueues.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ contract DeployQueues is DeployGeneralManager {
// Set the withdrawal gas fee
UsdxQueue(address(usdxQueue)).setWithdrawalGasFee(usdxWithdrawalGasFee);

// Renounce admin role
// Renounce admin role // Disable for production
UsdxQueue(address(usdxQueue)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}

Expand All @@ -69,7 +69,7 @@ contract DeployQueues is DeployGeneralManager {
// Set the withdrawal gas fee
ForfeitedAssetsQueue(address(forfeitedAssetsQueue)).setWithdrawalGasFee(forfeitedAssetsWithdrawalGasFee);

// Renounce admin role
// Renounce admin role // Disable for production
ForfeitedAssetsQueue(address(forfeitedAssetsQueue)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}

Expand Down Expand Up @@ -101,7 +101,7 @@ contract DeployQueues is DeployGeneralManager {
conversionQueue.setMortgageGasFee(conversionMortgageGasFee);
conversionQueue.setWithdrawalGasFee(conversionWithdrawalGasFee);

// Renounce admin role
// Renounce admin role // Disable for production
conversionQueue.renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);

// Push to the array of collateralQueues
Expand Down
2 changes: 1 addition & 1 deletion script/DeploySubConsols.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract DeploySubConsols is CollateralSetup {
// Grant the accounting role to the corresponding conversion queue (they're ordered the same)
SubConsol(address(subConsols[i])).grantRole(Roles.ACCOUNTING_ROLE, address(conversionQueues[i]));

// Renounce admin role
// Renounce admin role // Disable for production
SubConsol(address(subConsols[i])).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}
}
Expand Down
2 changes: 1 addition & 1 deletion script/DeployUSDX.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract DeployUSDX is CollateralSetup {
USDX(address(usdx)).grantRole(Roles.DEFAULT_ADMIN_ROLE, admins[i]);
}

// Renounce roles
// Renounce roles // Disable for production
MultiTokenVault(address(usdx)).renounceRole(Roles.SUPPORTED_TOKEN_ROLE, deployerAddress);
USDX(address(usdx)).renounceRole(Roles.DEFAULT_ADMIN_ROLE, deployerAddress);
}
Expand Down
Loading