// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "../../src/PolicyManager.sol"; import "../../src/ComplianceRegistry.sol"; import "../../src/DebtRegistry.sol"; import "../../src/libraries/ReasonCodes.sol"; contract PolicyManagerTest is Test { PolicyManager public policyManager; ComplianceRegistry public complianceRegistry; DebtRegistry public debtRegistry; address public admin; address public policyOperator; address public token; address public user1; address public user2; address public bridge; function setUp() public { admin = address(0x1); policyOperator = address(0x2); token = address(0x100); user1 = address(0x10); user2 = address(0x20); bridge = address(0xB0); complianceRegistry = new ComplianceRegistry(admin); debtRegistry = new DebtRegistry(admin); policyManager = new PolicyManager(admin, address(complianceRegistry), address(debtRegistry)); // Set up compliant users vm.startPrank(admin); policyManager.grantRole(policyManager.POLICY_OPERATOR_ROLE(), policyOperator); complianceRegistry.grantRole(complianceRegistry.COMPLIANCE_ROLE(), admin); complianceRegistry.setCompliance(user1, true, 1, bytes32(0)); complianceRegistry.setCompliance(user2, true, 1, bytes32(0)); complianceRegistry.setCompliance(bridge, true, 1, bytes32(0)); vm.stopPrank(); } function test_canTransfer_paused() public { vm.prank(policyOperator); policyManager.setPaused(token, true); (bool allowed, bytes32 reason) = policyManager.canTransfer(token, user1, user2, 100); assertFalse(allowed); assertEq(reason, ReasonCodes.PAUSED); } function test_canTransfer_tokenFrozen() public { vm.prank(policyOperator); policyManager.freeze(token, user1, true); (bool allowed, bytes32 reason) = policyManager.canTransfer(token, user1, user2, 100); assertFalse(allowed); assertEq(reason, ReasonCodes.FROM_FROZEN); } function test_canTransfer_complianceFrozen() public { vm.prank(admin); complianceRegistry.setFrozen(user1, true); (bool allowed, bytes32 reason) = policyManager.canTransfer(token, user1, user2, 100); assertFalse(allowed); assertEq(reason, ReasonCodes.FROM_FROZEN); } function test_canTransfer_notCompliant() public { address nonCompliant = address(0x99); (bool allowed, bytes32 reason) = policyManager.canTransfer(token, nonCompliant, user2, 100); assertFalse(allowed); assertEq(reason, ReasonCodes.FROM_NOT_COMPLIANT); } function test_canTransfer_bridgeOnly() public { vm.startPrank(policyOperator); policyManager.setBridgeOnly(token, true); policyManager.setBridge(token, bridge); vm.stopPrank(); // Non-bridge transfer should fail (bool allowed, bytes32 reason) = policyManager.canTransfer(token, user1, user2, 100); assertFalse(allowed); assertEq(reason, ReasonCodes.BRIDGE_ONLY); // Bridge transfer should succeed (allowed, reason) = policyManager.canTransfer(token, user1, bridge, 100); assertTrue(allowed); assertEq(reason, ReasonCodes.OK); (allowed, reason) = policyManager.canTransfer(token, bridge, user2, 100); assertTrue(allowed); assertEq(reason, ReasonCodes.OK); } function test_canTransfer_ok() public { (bool allowed, bytes32 reason) = policyManager.canTransfer(token, user1, user2, 100); assertTrue(allowed); assertEq(reason, ReasonCodes.OK); } function test_setLienMode() public { vm.prank(policyOperator); policyManager.setLienMode(token, 1); assertEq(policyManager.lienMode(token), 1); vm.prank(policyOperator); policyManager.setLienMode(token, 2); assertEq(policyManager.lienMode(token), 2); } function test_setLienMode_invalid() public { vm.prank(policyOperator); vm.expectRevert("PolicyManager: invalid lien mode"); policyManager.setLienMode(token, 3); } function test_setBridge() public { vm.prank(policyOperator); policyManager.setBridge(token, bridge); assertEq(policyManager.bridge(token), bridge); } }