gcx/blockchain/genex-contracts/test/Compliance.t.sol

195 lines
5.7 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/Compliance.sol";
import "../src/interfaces/ICoupon.sol";
contract ComplianceTest is Test {
Compliance compliance;
address admin = address(1);
address user1 = address(2);
address user2 = address(3);
address officer = address(4);
function setUp() public {
vm.startPrank(admin);
compliance = new Compliance();
compliance.initialize(admin);
compliance.grantRole(keccak256("COMPLIANCE_OFFICER_ROLE"), officer);
vm.stopPrank();
}
// === OFAC ===
function test_AddToBlacklist() public {
vm.prank(officer);
compliance.addToBlacklist(user1, "OFAC SDN");
assertTrue(compliance.isBlacklisted(user1));
}
function test_RemoveFromBlacklist() public {
vm.prank(officer);
compliance.addToBlacklist(user1, "OFAC SDN");
vm.prank(admin);
compliance.removeFromBlacklist(user1);
assertFalse(compliance.isBlacklisted(user1));
}
function test_RemoveFromBlacklistOnlyGovernance() public {
vm.prank(officer);
compliance.addToBlacklist(user1, "OFAC SDN");
vm.prank(officer);
vm.expectRevert();
compliance.removeFromBlacklist(user1);
}
// === KYC ===
function test_SetKycLevel() public {
vm.prank(admin);
compliance.setKycLevel(user1, 2);
assertEq(compliance.getKycLevel(user1), 2);
}
function test_InvalidKycLevelReverts() public {
vm.prank(admin);
vm.expectRevert("Compliance: invalid KYC level");
compliance.setKycLevel(user1, 4);
}
function test_RequireKycLevelSuccess() public view {
// L0 默认
compliance.requireKycLevel(user1, 0);
}
function test_RequireKycLevelFails() public {
vm.expectRevert("Compliance: insufficient KYC level");
compliance.requireKycLevel(user1, 1);
}
function test_BatchSetKycLevel() public {
address[] memory accounts = new address[](2);
accounts[0] = user1;
accounts[1] = user2;
uint8[] memory levels = new uint8[](2);
levels[0] = 1;
levels[1] = 2;
vm.prank(admin);
compliance.batchSetKycLevel(accounts, levels);
assertEq(compliance.getKycLevel(user1), 1);
assertEq(compliance.getKycLevel(user2), 2);
}
// === Freeze ===
function test_FreezeAccount() public {
vm.prank(admin);
compliance.freezeAccount(user1);
assertTrue(compliance.isFrozen(user1));
}
function test_UnfreezeAccount() public {
vm.prank(admin);
compliance.freezeAccount(user1);
vm.prank(admin);
compliance.unfreezeAccount(user1);
assertFalse(compliance.isFrozen(user1));
}
// === Travel Rule ===
function test_RecordTravelRule() public {
vm.prank(officer);
compliance.recordTravelRule(user1, user2, keccak256("sender"), keccak256("receiver"));
assertTrue(compliance.hasTravelRuleRecord(user1, user2));
}
// === Pre-Trade Check ===
function test_PreTradeCheckUtilityRequiresKycL1() public {
// 无 KYC
vm.expectRevert("Compliance: buyer needs KYC L1 for Utility");
compliance.preTradeCheck(user1, user2, 100e6, ICoupon.CouponType.Utility);
}
function test_PreTradeCheckSecurityRequiresKycL2() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 1);
compliance.setKycLevel(user2, 1);
vm.stopPrank();
vm.expectRevert("Compliance: buyer needs KYC L2 for Security");
compliance.preTradeCheck(user1, user2, 100e6, ICoupon.CouponType.Security);
}
function test_PreTradeCheckLargeTradeRequiresKycL2() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 1);
compliance.setKycLevel(user2, 1);
vm.stopPrank();
vm.expectRevert("Compliance: buyer needs KYC L2 for large trade");
compliance.preTradeCheck(user1, user2, 10000e6, ICoupon.CouponType.Utility);
}
function test_PreTradeCheckBlacklistedReverts() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 2);
compliance.setKycLevel(user2, 2);
vm.stopPrank();
vm.prank(officer);
compliance.addToBlacklist(user1, "OFAC");
vm.expectRevert("Compliance: buyer blacklisted");
compliance.preTradeCheck(user1, user2, 100e6, ICoupon.CouponType.Utility);
}
function test_PreTradeCheckFrozenReverts() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 2);
compliance.setKycLevel(user2, 2);
compliance.freezeAccount(user2);
vm.stopPrank();
vm.expectRevert("Compliance: seller frozen");
compliance.preTradeCheck(user1, user2, 100e6, ICoupon.CouponType.Utility);
}
// === P2P Check ===
function test_P2pCheckRequiresTravelRule() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 2);
compliance.setKycLevel(user2, 2);
vm.stopPrank();
vm.expectRevert("Compliance: Travel Rule data required");
compliance.p2pComplianceCheck(user1, user2, 5000e6);
}
function test_P2pCheckWithTravelRuleSuccess() public {
vm.startPrank(admin);
compliance.setKycLevel(user1, 2);
compliance.setKycLevel(user2, 2);
vm.stopPrank();
vm.prank(officer);
compliance.recordTravelRule(user1, user2, keccak256("s"), keccak256("r"));
// 不应 revert
compliance.p2pComplianceCheck(user1, user2, 5000e6);
}
function test_P2pCheckBelowThresholdNoTravelRule() public {
// $2,999 无需 Travel Rule
compliance.p2pComplianceCheck(user1, user2, 2999e6);
}
}