refactor(archive): move historical contracts and adapters to archive directory

- Archived multiple non-EVM adapters (Algorand, Hedera, Tron, TON, Cosmos, Solana) and compliance contracts (IndyVerifier) to `archive/solidity/contracts/`.
- Updated documentation to reflect the historical status of archived components.
- Adjusted `foundry.toml` and `README.md` for clarity on historical dependencies and configurations.
- Enhanced Makefile and package.json scripts for improved contract testing and building processes.
- Removed obsolete contracts (AlltraCustomBridge, CommodityCCIPBridge, ISO4217WCCIPBridge, VaultBridgeAdapter) from the main directory.
- Updated implementation reports to indicate archived status for various components.
This commit is contained in:
defiQUG
2026-04-12 18:21:05 -07:00
parent 8ec6af94d5
commit 2b52cc6e32
146 changed files with 2010 additions and 423 deletions

View File

@@ -0,0 +1,50 @@
// 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 {AaveQuotePushFlashReceiver} from "../../contracts/flash/AaveQuotePushFlashReceiver.sol";
contract MockSweepToken is ERC20 {
constructor() ERC20("Mock Sweep Token", "MST") {}
function mint(address to, uint256 amount) external {
_mint(to, amount);
}
}
contract AaveQuotePushFlashReceiverTest is Test {
AaveQuotePushFlashReceiver internal receiver;
MockSweepToken internal token;
function setUp() public {
receiver = new AaveQuotePushFlashReceiver(address(0x1234), address(this));
token = new MockSweepToken();
token.mint(address(receiver), 1_000_000);
}
function testOwnerCanSweepQuoteSurplusAndKeepReserve() public {
uint256 reserveRetained = 250_000;
uint256 sweepable = receiver.quoteSurplusBalance(address(token), reserveRetained);
assertEq(sweepable, 750_000, "sweepable amount should exclude retained reserve");
receiver.sweepQuoteSurplus(address(token), address(this), reserveRetained);
assertEq(token.balanceOf(address(receiver)), reserveRetained, "receiver should keep reserve");
assertEq(token.balanceOf(address(this)), 750_000, "owner should receive swept surplus");
}
function testNonOwnerCannotSweep() public {
vm.prank(address(0xBEEF));
vm.expectRevert();
receiver.sweepQuoteSurplus(address(token), address(0xBEEF), 0);
}
function testOwnerCanSweepExplicitTokenAmount() public {
receiver.sweepToken(address(token), address(0xCAFE), 123_456);
assertEq(token.balanceOf(address(receiver)), 876_544, "receiver balance should decrease");
assertEq(token.balanceOf(address(0xCAFE)), 123_456, "recipient should receive exact amount");
}
}

View File

@@ -67,7 +67,7 @@ contract AaveQuotePushFlashReceiverMainnetForkTest is Test {
return;
}
receiver = new AaveQuotePushFlashReceiver(AAVE_POOL_MAINNET);
receiver = new AaveQuotePushFlashReceiver(AAVE_POOL_MAINNET, address(this));
unwinder = new AaveForkMockExternalUnwinder(IERC20(CWUSDC), IERC20(USDC), 112, 100);
// PMM + unwind sizing can require materially more than 100 USDC on a live reserve snapshot.
deal(USDC, address(unwinder), 50_000_000_000); // 50k USDC (6 decimals) for mock unwind payouts
@@ -113,4 +113,47 @@ contract AaveQuotePushFlashReceiverMainnetForkTest is Test {
assertLt(poolBaseAfter, poolBaseBefore, "pool base decreased via quote push");
assertGt(poolQuoteAfter, poolQuoteBefore, "pool quote increased via quote push");
}
function testFork_ownerCanSweepRetainedQuoteSurplus() public skipIfNoFork {
uint256 amount = 2_964_298;
address recipient = address(0xBEEF);
AaveQuotePushFlashReceiver.QuotePushParams memory p = AaveQuotePushFlashReceiver.QuotePushParams({
integration: DODO_PMM_INTEGRATION_MAINNET,
pmmPool: POOL_CWUSDC_USDC,
baseToken: CWUSDC,
externalUnwinder: address(unwinder),
minOutPmm: 2_800_000,
minOutUnwind: amount + 1_483,
unwindData: bytes(""),
atomicBridge: AaveQuotePushFlashReceiver.AtomicBridgeParams({
coordinator: address(0),
sourceChain: 0,
destinationChain: 0,
destinationAsset: address(0),
bridgeAmount: 0,
minDestinationAmount: 0,
destinationRecipient: address(0),
destinationDeadline: 0,
routeId: bytes32(0),
settlementMode: bytes32(0),
submitCommitment: false
})
});
receiver.flashQuotePush(USDC, amount, p);
uint256 retainedBeforeSweep = IERC20(USDC).balanceOf(address(receiver));
uint256 reserveRetained = 10_000;
uint256 expectedSweep = retainedBeforeSweep - reserveRetained;
uint256 sweepable = receiver.quoteSurplusBalance(USDC, reserveRetained);
assertEq(sweepable, expectedSweep, "sweepable balance excludes retained reserve");
uint256 recipientBefore = IERC20(USDC).balanceOf(recipient);
receiver.sweepQuoteSurplus(USDC, recipient, reserveRetained);
assertEq(IERC20(USDC).balanceOf(address(receiver)), reserveRetained, "receiver keeps configured reserve");
assertEq(IERC20(USDC).balanceOf(recipient), recipientBefore + expectedSweep, "recipient receives swept surplus");
}
}

View File

@@ -0,0 +1,109 @@
// 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 {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {QuotePushTreasuryManager} from "../../contracts/flash/QuotePushTreasuryManager.sol";
contract MockTreasuryToken is ERC20 {
constructor() ERC20("Mock Treasury Token", "MTT") {}
function mint(address to, uint256 amount) external {
_mint(to, amount);
}
}
contract MockSweepableReceiver is Ownable {
using SafeERC20 for IERC20;
IERC20 internal immutable token;
constructor(address initialOwner, IERC20 token_) Ownable(initialOwner) {
token = token_;
}
function quoteSurplusBalance(address quoteToken, uint256 reserveRetained) external view returns (uint256 surplus) {
require(quoteToken == address(token), "wrong token");
uint256 balance = token.balanceOf(address(this));
if (balance > reserveRetained) {
surplus = balance - reserveRetained;
}
}
function sweepQuoteSurplus(address quoteToken, address to, uint256 reserveRetained)
external
onlyOwner
returns (uint256 amount)
{
require(quoteToken == address(token), "wrong token");
uint256 balance = token.balanceOf(address(this));
require(balance > reserveRetained, "nothing to sweep");
amount = balance - reserveRetained;
token.safeTransfer(to, amount);
}
}
contract QuotePushTreasuryManagerTest is Test {
MockTreasuryToken internal token;
MockSweepableReceiver internal receiver;
QuotePushTreasuryManager internal manager;
address internal constant OPERATOR = address(0xBEEF);
address internal constant GAS_RECIPIENT = address(0xCAFE);
address internal constant RECYCLE_RECIPIENT = address(0xF00D);
function setUp() public {
token = new MockTreasuryToken();
receiver = new MockSweepableReceiver(address(this), token);
manager = new QuotePushTreasuryManager(
address(this), address(receiver), address(token), OPERATOR, GAS_RECIPIENT, RECYCLE_RECIPIENT, 200_000, 100_000
);
receiver.transferOwnership(address(manager));
token.mint(address(receiver), 1_000_000);
}
function testHarvestReceiverSurplusKeepsReceiverReserve() public {
assertTrue(manager.isReceiverOwnedByManager(), "manager should own receiver");
assertEq(manager.receiverSweepableQuote(), 800_000, "sweepable quote should exclude receiver reserve");
uint256 harvested = manager.harvestReceiverSurplus();
assertEq(harvested, 800_000, "harvested amount should match receiver surplus");
assertEq(token.balanceOf(address(receiver)), 200_000, "receiver should keep configured reserve");
assertEq(manager.quoteBalance(), 800_000, "manager should receive harvested quote");
assertEq(manager.availableQuote(), 700_000, "manager reserve should be retained");
}
function testOperatorCanDistributeConfiguredRecipients() public {
manager.harvestReceiverSurplus();
vm.prank(OPERATOR);
manager.distributeToConfiguredRecipients(250_000, 300_000);
assertEq(token.balanceOf(GAS_RECIPIENT), 250_000, "gas recipient should receive configured amount");
assertEq(token.balanceOf(RECYCLE_RECIPIENT), 300_000, "recycle recipient should receive configured amount");
assertEq(manager.quoteBalance(), 250_000, "manager should retain the undistributed quote");
assertEq(manager.availableQuote(), 150_000, "manager reserve should still be protected");
}
function testDistributeRevertsWhenRequestedAmountExceedsAvailable() public {
manager.harvestReceiverSurplus();
vm.prank(OPERATOR);
vm.expectRevert();
manager.distributeToConfiguredRecipients(500_000, 250_001);
}
function testOwnerCanRescueNonQuoteToken() public {
MockTreasuryToken other = new MockTreasuryToken();
other.mint(address(manager), 42);
manager.rescueToken(address(other), address(this), 42);
assertEq(other.balanceOf(address(this)), 42, "owner should be able to rescue unrelated tokens");
}
}