Files
smom-dbis-138/test/cw-settlement/CWReserveSettlementStack.t.sol

141 lines
4.4 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Test} from "forge-std/Test.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {CWNavOracle} from "../../contracts/cw-settlement/CWNavOracle.sol";
import {CWRedemptionQueue} from "../../contracts/cw-settlement/CWRedemptionQueue.sol";
import {CWStabilityFund} from "../../contracts/cw-settlement/CWStabilityFund.sol";
contract MockNavBridge {
mapping(address => uint256) internal _locked;
mapping(address => uint256) internal _outstanding;
function setLocked(address token, uint256 amount) external {
_locked[token] = amount;
}
function lockedBalance(address token) external view returns (uint256) {
return _locked[token];
}
function totalOutstanding(address token) external view returns (uint256) {
return _outstanding[token];
}
}
contract MockReserveSystem {
mapping(address => uint256) internal _balances;
function setBalance(address asset, uint256 amount) external {
_balances[asset] = amount;
}
function getReserveBalance(address asset) external view returns (uint256) {
return _balances[asset];
}
}
contract MockERC20Six is ERC20 {
constructor() ERC20("Mock", "MOCK") {}
function mint(address to, uint256 amount) external {
_mint(to, amount);
}
function decimals() public pure override returns (uint8) {
return 6;
}
}
contract CWNavOracleTest is Test {
MockNavBridge internal bridge;
MockReserveSystem internal reserveSystem;
CWNavOracle internal navOracle;
MockERC20Six internal canonical;
function setUp() public {
bridge = new MockNavBridge();
reserveSystem = new MockReserveSystem();
navOracle = new CWNavOracle(address(this), address(bridge), address(reserveSystem));
canonical = new MockERC20Six();
navOracle.configureToken(address(canonical), address(canonical));
}
function test_publishNav_computesBackingAndNavPerShare() public {
bridge.setLocked(address(canonical), 120 * 1e6);
reserveSystem.setBalance(address(canonical), 30 * 1e6);
navOracle.publishNav(
address(canonical),
100 * 1e6,
8200,
1500,
300,
keccak256("attestation-v1")
);
CWNavOracle.NavSnapshot memory snap = navOracle.getNavSnapshot(address(canonical));
assertEq(snap.totalLockedAssets, 120 * 1e6);
assertEq(snap.totalReserveAssets, 30 * 1e6);
assertEq(snap.totalCwSupply, 100 * 1e6);
assertEq(snap.backingRatioBps, 15000);
assertEq(snap.navPerShare, 15e17);
}
}
contract CWRedemptionQueueTest is Test {
CWRedemptionQueue internal queue;
MockERC20Six internal token;
function setUp() public {
queue = new CWRedemptionQueue(address(this));
token = new MockERC20Six();
queue.grantRole(queue.BRIDGE_ROLE(), address(this));
}
function test_instantTier_claimableImmediately() public {
token.mint(address(this), 1_000 * 1e6);
token.approve(address(queue), 1_000 * 1e6);
uint256 requestId = queue.fundAndEnqueue(address(this), address(token), 1_000 * 1e6);
queue.claim(requestId);
assertEq(token.balanceOf(address(this)), 1_000 * 1e6);
}
function test_standardTier_requiresDelay() public {
uint256 requestId = queue.enqueueRedemption(address(this), address(token), 10_000 * 1e6);
vm.expectRevert();
queue.claim(requestId);
vm.warp(block.timestamp + 24 hours);
queue.processDueRequests(_arr(requestId));
vm.expectRevert();
queue.claim(requestId);
}
function _arr(uint256 id) internal pure returns (uint256[] memory ids) {
ids = new uint256[](1);
ids[0] = id;
}
}
contract CWStabilityFundTest is Test {
CWStabilityFund internal fund;
MockERC20Six internal token;
function setUp() public {
fund = new CWStabilityFund(address(this));
token = new MockERC20Six();
fund.setSupportedAsset(address(token), true);
}
function test_depositAndEmergencyWithdraw() public {
token.mint(address(this), 100e6);
token.approve(address(fund), 100e6);
fund.deposit(address(token), 100e6);
fund.emergencyWithdraw(address(token), address(this), 50e6, keccak256("depeg"));
assertEq(token.balanceOf(address(this)), 50e6);
}
}