- Add Foundry project configuration (foundry.toml, foundry.lock) - Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.) - Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI) - Add comprehensive test suite (unit, integration, fuzz, invariants) - Add API services (REST, GraphQL, orchestrator, packet service) - Add documentation (ISO20022 mapping, runbooks, adapter guides) - Add development tools (RBC tool, Swagger UI, mock server) - Update OpenZeppelin submodules to v5.0.0
145 lines
4.4 KiB
Solidity
145 lines
4.4 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "forge-std/Test.sol";
|
|
import "../../src/DebtRegistry.sol";
|
|
import "../../src/interfaces/IDebtRegistry.sol";
|
|
|
|
contract DebtRegistryFuzz is Test {
|
|
DebtRegistry public registry;
|
|
address public admin;
|
|
address public debtAuthority;
|
|
|
|
struct LienState {
|
|
uint256 id;
|
|
address debtor;
|
|
uint256 amount;
|
|
bool active;
|
|
}
|
|
|
|
LienState[] public lienStates;
|
|
|
|
function setUp() public {
|
|
admin = address(0x1);
|
|
debtAuthority = address(0x2);
|
|
|
|
registry = new DebtRegistry(admin);
|
|
|
|
vm.startPrank(admin);
|
|
registry.grantRole(registry.DEBT_AUTHORITY_ROLE(), debtAuthority);
|
|
vm.stopPrank();
|
|
}
|
|
|
|
function testFuzz_placeAndReleaseLiens(
|
|
address debtor,
|
|
uint256 amount,
|
|
uint64 expiry
|
|
) public {
|
|
vm.assume(debtor != address(0));
|
|
vm.assume(amount > 0 && amount < type(uint128).max);
|
|
|
|
uint256 initialEncumbrance = registry.activeLienAmount(debtor);
|
|
uint256 initialCount = registry.activeLienCount(debtor);
|
|
|
|
vm.prank(debtAuthority);
|
|
uint256 lienId = registry.placeLien(debtor, amount, expiry, 1, bytes32(0));
|
|
|
|
assertEq(registry.activeLienAmount(debtor), initialEncumbrance + amount);
|
|
assertEq(registry.activeLienCount(debtor), initialCount + 1);
|
|
|
|
vm.prank(debtAuthority);
|
|
registry.releaseLien(lienId);
|
|
|
|
assertEq(registry.activeLienAmount(debtor), initialEncumbrance);
|
|
assertEq(registry.activeLienCount(debtor), initialCount);
|
|
}
|
|
|
|
function testFuzz_reduceLien(uint256 initialAmount, uint256 reduceBy) public {
|
|
vm.assume(initialAmount > 0 && initialAmount < type(uint128).max);
|
|
vm.assume(reduceBy <= initialAmount);
|
|
|
|
address debtor = address(0x100);
|
|
|
|
vm.prank(debtAuthority);
|
|
uint256 lienId = registry.placeLien(debtor, initialAmount, 0, 1, bytes32(0));
|
|
|
|
uint256 expectedEncumbrance = initialAmount - reduceBy;
|
|
|
|
vm.prank(debtAuthority);
|
|
registry.reduceLien(lienId, reduceBy);
|
|
|
|
assertEq(registry.activeLienAmount(debtor), expectedEncumbrance);
|
|
|
|
IDebtRegistry.Lien memory lien = registry.getLien(lienId);
|
|
assertEq(lien.amount, expectedEncumbrance);
|
|
assertTrue(lien.active);
|
|
}
|
|
|
|
function testFuzz_reduceLien_exceedsAmount(uint256 initialAmount, uint256 reduceBy) public {
|
|
vm.assume(initialAmount > 0 && initialAmount < type(uint128).max);
|
|
vm.assume(reduceBy > initialAmount);
|
|
|
|
address debtor = address(0x100);
|
|
|
|
vm.prank(debtAuthority);
|
|
uint256 lienId = registry.placeLien(debtor, initialAmount, 0, 1, bytes32(0));
|
|
|
|
vm.prank(debtAuthority);
|
|
vm.expectRevert("DebtRegistry: reduceBy exceeds amount");
|
|
registry.reduceLien(lienId, reduceBy);
|
|
}
|
|
|
|
function testFuzz_multipleLiens(
|
|
address debtor,
|
|
uint256[5] memory amounts
|
|
) public {
|
|
vm.assume(debtor != address(0));
|
|
|
|
uint256 totalExpected = 0;
|
|
uint256[] memory lienIds = new uint256[](5);
|
|
bool[] memory placed = new bool[](5);
|
|
|
|
for (uint256 i = 0; i < 5; i++) {
|
|
if (amounts[i] > 0 && amounts[i] < type(uint128).max) {
|
|
vm.prank(debtAuthority);
|
|
lienIds[i] = registry.placeLien(debtor, amounts[i], 0, 1, bytes32(0));
|
|
totalExpected += amounts[i];
|
|
placed[i] = true;
|
|
}
|
|
}
|
|
|
|
assertEq(registry.activeLienAmount(debtor), totalExpected);
|
|
|
|
// Release all liens that were placed
|
|
for (uint256 i = 0; i < 5; i++) {
|
|
if (placed[i]) {
|
|
vm.prank(debtAuthority);
|
|
registry.releaseLien(lienIds[i]);
|
|
}
|
|
}
|
|
|
|
assertEq(registry.activeLienAmount(debtor), 0);
|
|
assertEq(registry.activeLienCount(debtor), 0);
|
|
}
|
|
|
|
function testFuzz_encumbranceAlwaysNonNegative(
|
|
address debtor,
|
|
uint256 amount,
|
|
uint256 reduceBy
|
|
) public {
|
|
vm.assume(debtor != address(0));
|
|
vm.assume(amount > 0 && amount < type(uint128).max);
|
|
vm.assume(reduceBy <= amount);
|
|
|
|
vm.prank(debtAuthority);
|
|
uint256 lienId = registry.placeLien(debtor, amount, 0, 1, bytes32(0));
|
|
|
|
vm.prank(debtAuthority);
|
|
registry.reduceLien(lienId, reduceBy);
|
|
|
|
uint256 encumbrance = registry.activeLienAmount(debtor);
|
|
assertGe(encumbrance, 0); // Should never underflow
|
|
}
|
|
}
|
|
|