-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CBL TGE Staking campaign
- Loading branch information
Showing
28 changed files
with
1,236 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
## | ||
# The Application Configuration for the TestNet Environment. | ||
## | ||
|
||
[evm] | ||
# blockchain id, e.g. baseSepolia=84532, arbSepolia=421614 | ||
chain_id = 84532 | ||
deploy_mocks = false | ||
|
||
[evm.address] | ||
# credbull-devops wallets. wallet numbers are 1-based (as opposed to 0-based in anvil) | ||
# devops admin/owner (wallet 1) - public address, okay to share | ||
owner = "0xD79Be36f61fce3B8EF2FBF22b13B2b9a68eE15A2" | ||
# devops operator (wallet 2) - public address, okay to share | ||
operator = "0xaD3C004eE1f942BFDA2DA0D2DAaC94d6aC012F75" | ||
# devops custodian (wallet 3) - public address, okay to share | ||
custodian = "0x8561845F6a9511cD8e2daCae77A961e718A77cF6" | ||
# devops upgrader (wallet 4) - public address, okay to share | ||
upgrader = "0xaD3C004eE1f942BFDA2DA0D2DAaC94d6aC012F75" | ||
# devops asset manager (wallet 7) - public address, okay to share | ||
asset_manager = "0xd097E901FB9B75C2d2f97E142d73fA79C31FcAb3" | ||
# CBL token address - Base Sepolia | ||
cbl_token="0x2064334877Fac12f353b8FB42440805709eC267A" | ||
# USDC token address - Base Sepolia | ||
usdc_token="0x036CbD53842c5426634e7929541eC2318f3dCF7e" | ||
|
||
[evm.contracts.liquid_continuous_multi_token_vault] | ||
# rate in basis points, e.g. 10% = 1000 bps | ||
full_rate_bps = 10_00 | ||
# rate in basis points, e.g. 5.5% = 550 bps | ||
reduced_rate_bps = 5_50 | ||
|
||
[evm.contracts.upside_vault] | ||
# 2 decimal place percentage (meaining value divided by 100) as integer. | ||
collateral_percentage = 200 | ||
|
||
[evm.contracts.cbl] | ||
# CBL token params | ||
# devops admin/owner (wallet 1) - public address, okay to share | ||
owner = "0xD79Be36f61fce3B8EF2FBF22b13B2b9a68eE15A2" | ||
# devops operator (wallet 2) - public address, okay to share | ||
minter = "0xaD3C004eE1f942BFDA2DA0D2DAaC94d6aC012F75" | ||
# CBL token params | ||
max_supply = 10_000_000 # 10 million in wei | ||
|
||
[services.supabase] | ||
url = "https://kyvvhlnmoqibdihqrlmc.supabase.co" | ||
|
||
# Save the contract deployment details to the database. | ||
update_contract_addresses = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
//SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import { Script } from "forge-std/Script.sol"; | ||
|
||
import { HelperConfig, NetworkConfig } from "@script/HelperConfig.s.sol"; | ||
|
||
import { CredbullFixedYieldVaultFactory } from "@credbull/CredbullFixedYieldVaultFactory.sol"; | ||
import { CredbullFixedYieldVault } from "@credbull/CredbullFixedYieldVault.sol"; | ||
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import { Vault } from "@credbull/vault/Vault.sol"; | ||
import { MaturityVault } from "@credbull/vault/MaturityVault.sol"; | ||
import { FixedYieldVault } from "@credbull/vault/FixedYieldVault.sol"; | ||
import { WindowPlugin } from "@credbull/plugin/WindowPlugin.sol"; | ||
import { WhiteListPlugin } from "@credbull/plugin/WhiteListPlugin.sol"; | ||
import { MaxCapPlugin } from "@credbull/plugin/MaxCapPlugin.sol"; | ||
|
||
import { console2 } from "forge-std/console2.sol"; | ||
|
||
contract DeployStakingVaults is Script { | ||
bool private isTestMode; | ||
|
||
function runTest() | ||
public | ||
returns ( | ||
CredbullFixedYieldVaultFactory factory, | ||
CredbullFixedYieldVault stakingVault50APY_, | ||
CredbullFixedYieldVault stakingVault0APY_, | ||
HelperConfig helperConfig | ||
) | ||
{ | ||
isTestMode = true; | ||
return run(); | ||
} | ||
|
||
function run() | ||
public | ||
returns ( | ||
CredbullFixedYieldVaultFactory factory, | ||
CredbullFixedYieldVault stakingVault50APY_, | ||
CredbullFixedYieldVault stakingVault0APY_, | ||
HelperConfig helperConfig | ||
) | ||
{ | ||
helperConfig = new HelperConfig(isTestMode); | ||
|
||
vm.startBroadcast(); | ||
|
||
CredbullFixedYieldVault stakingVault50APY = new CredbullFixedYieldVault( | ||
createStakingVaultParams(helperConfig, "inCredbull Earn CBL Staking Challenge", "iceCBLsc", 50) | ||
); | ||
console2.log( | ||
string.concat( | ||
"!!!!! Deploying CredbullFixedYieldVault 50APY [", vm.toString(address(stakingVault50APY)), "] !!!!!" | ||
) | ||
); | ||
|
||
CredbullFixedYieldVault stakingVault0APY = new CredbullFixedYieldVault( | ||
createStakingVaultParams(helperConfig, "inCredbull Earn CBL Booster Vault", "iceCBLBooster", 0) | ||
); | ||
console2.log( | ||
string.concat( | ||
"!!!!! Deploying CredbullFixedYieldVault OAPY [", vm.toString(address(stakingVault0APY)), "] !!!!!" | ||
) | ||
); | ||
|
||
vm.stopBroadcast(); | ||
|
||
return (factory, stakingVault50APY, stakingVault0APY, helperConfig); | ||
} | ||
|
||
function createStakingVaultParams( | ||
HelperConfig helperConfig, | ||
string memory shareName, | ||
string memory shareSymbol, | ||
uint256 _yieldPercentage | ||
) internal view returns (CredbullFixedYieldVault.FixedYieldVaultParams memory) { | ||
NetworkConfig memory config = helperConfig.getNetworkConfig(); | ||
Vault.VaultParams memory _vaultParams = Vault.VaultParams({ | ||
asset: IERC20(config.cblToken), | ||
shareName: shareName, | ||
shareSymbol: shareSymbol, | ||
custodian: config.factoryParams.custodian | ||
}); | ||
|
||
MaturityVault.MaturityVaultParams memory _maturityVaultParams = | ||
MaturityVault.MaturityVaultParams({ vault: _vaultParams }); | ||
|
||
FixedYieldVault.ContractRoles memory _contractRoles = FixedYieldVault.ContractRoles({ | ||
owner: config.factoryParams.owner, | ||
operator: config.factoryParams.operator, | ||
custodian: config.factoryParams.custodian | ||
}); | ||
|
||
uint256 depositStart = 1730973600; // Deposit Start: Nov 7 10 AM UTC - okay | ||
WindowPlugin.Window memory _depositWindow = | ||
WindowPlugin.Window({ opensAt: depositStart, closesAt: depositStart + 14 days - 1 }); | ||
|
||
uint256 redeemStart = _depositWindow.closesAt + 30 days + 1; // Withdraw Start: Deposit End + 30 days | ||
WindowPlugin.Window memory _redemptionWindow = | ||
WindowPlugin.Window({ opensAt: (redeemStart), closesAt: (redeemStart + 30 days - 1) }); | ||
|
||
_logWindowTimestamps(_depositWindow, _redemptionWindow); | ||
|
||
WindowPlugin.WindowPluginParams memory _windowPluginParams = | ||
WindowPlugin.WindowPluginParams({ depositWindow: _depositWindow, redemptionWindow: _redemptionWindow }); | ||
|
||
WhiteListPlugin.WhiteListPluginParams memory _whiteListPluginParams = WhiteListPlugin.WhiteListPluginParams({ | ||
whiteListProvider: config.factoryParams.owner, // using owner as the whitelist provider | ||
depositThresholdForWhiteListing: type(uint256).max // logically disable the whitelist | ||
}); | ||
|
||
uint256 maxCap = 10_000_000 ether; | ||
MaxCapPlugin.MaxCapPluginParams memory _maxCapPluginParams = MaxCapPlugin.MaxCapPluginParams({ maxCap: maxCap }); // Max cap not necessary for staking vaults | ||
|
||
return FixedYieldVault.FixedYieldVaultParams({ | ||
maturityVault: _maturityVaultParams, | ||
roles: _contractRoles, | ||
windowPlugin: _windowPluginParams, | ||
whiteListPlugin: _whiteListPluginParams, | ||
maxCapPlugin: _maxCapPluginParams, | ||
promisedYield: _yieldPercentage | ||
}); | ||
} | ||
|
||
//@dev - see https://www.epochconverter.com/batch#results | ||
function _logWindowTimestamps(WindowPlugin.Window memory depositWindow, WindowPlugin.Window memory redemptionWindow) | ||
internal | ||
pure | ||
{ | ||
console2.log("==============================================================="); | ||
console2.log("Vault windows: depositStart, depositEnd, redeemStart, redeemEnd"); | ||
console2.log("==============================================================="); | ||
console2.log(depositWindow.opensAt); | ||
console2.log(depositWindow.closesAt); | ||
console2.log(redemptionWindow.opensAt); | ||
console2.log(redemptionWindow.closesAt); | ||
console2.log("==============================================================="); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
packages/contracts/test/src/CredbullFixedYieldVaultStakingTest.t.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import { Test } from "forge-std/Test.sol"; | ||
|
||
import { HelperConfig } from "@script/HelperConfig.s.sol"; | ||
import { DeployStakingVaults } from "@script/DeployStakingVaults.s.sol"; | ||
import { CredbullFixedYieldVault } from "@credbull/CredbullFixedYieldVault.sol"; | ||
|
||
import { CBL } from "@credbull/token/CBL.sol"; | ||
|
||
contract CredbullFixedYieldVaultStakingTest is Test { | ||
CredbullFixedYieldVault private vault50APY; | ||
CredbullFixedYieldVault private vault0APY; | ||
HelperConfig private helperConfig; | ||
|
||
CBL private cbl; | ||
|
||
address private alice = makeAddr("alice"); | ||
address private bob = makeAddr("bob"); | ||
|
||
address private owner; | ||
address private operator; | ||
address private minter; | ||
|
||
uint256 private precision; | ||
uint256 private constant INITIAL_BALANCE = 1000; | ||
|
||
function setUp() public { | ||
DeployStakingVaults deployStakingVaults = new DeployStakingVaults(); | ||
(, vault50APY, vault0APY, helperConfig) = deployStakingVaults.run(); | ||
|
||
cbl = CBL(vault50APY.asset()); | ||
precision = 10 ** cbl.decimals(); | ||
|
||
assertEq(10 ** 18, precision, "should be 10^18"); | ||
|
||
owner = helperConfig.getNetworkConfig().factoryParams.owner; | ||
operator = helperConfig.getNetworkConfig().factoryParams.operator; | ||
minter = helperConfig.getNetworkConfig().factoryParams.operator; | ||
|
||
vm.startPrank(minter); | ||
cbl.mint(alice, INITIAL_BALANCE * precision); | ||
cbl.mint(bob, INITIAL_BALANCE * precision); | ||
vm.stopPrank(); | ||
|
||
assertEq(INITIAL_BALANCE * precision, cbl.balanceOf(alice), "alice didn't receive CBL"); | ||
} | ||
|
||
function test__FixedYieldVaultStakingChallenge__Expect50APY() public { | ||
uint256 depositAmount = 10 * precision; | ||
uint256 expectedAssets = ((depositAmount * (100 + 50)) / 100); | ||
|
||
depositAndVerify(vault50APY, depositAmount, expectedAssets); | ||
} | ||
|
||
function test__FixedYieldVaultStakingChallenge__Expect0APY() public { | ||
uint256 depositAmount = 10 * precision; | ||
|
||
depositAndVerify(vault0APY, depositAmount, depositAmount); | ||
} | ||
|
||
function depositAndVerify(CredbullFixedYieldVault vault, uint256 depositAmount, uint256 expectedAssets) public { | ||
assertTrue(vault.checkWindow(), "window should be on"); | ||
|
||
vm.prank(owner); | ||
vault.toggleWindowCheck(); | ||
assertFalse(vault.checkWindow(), "window should be off"); | ||
|
||
vm.startPrank(alice); | ||
cbl.approve(address(vault), depositAmount); | ||
uint256 shares = vault.deposit(depositAmount, alice); | ||
vm.stopPrank(); | ||
|
||
assertEq(depositAmount, cbl.balanceOf(vault.CUSTODIAN()), "custodian should have the CBL"); | ||
assertEq(shares, vault.balanceOf(alice), "alice should have the shares"); | ||
|
||
assertEq(vault.expectedAssetsOnMaturity(), expectedAssets); | ||
} | ||
} |
Oops, something went wrong.