diff --git a/solidity/test/unit/modules/access/WhitelistAccessModule.t.sol b/solidity/test/unit/modules/access/WhitelistAccessModule.t.sol new file mode 100644 index 0000000..db1e748 --- /dev/null +++ b/solidity/test/unit/modules/access/WhitelistAccessModule.t.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import 'forge-std/Test.sol'; + +import {Helpers} from '../../../utils/Helpers.sol'; + +import {IModule} from '@defi-wonderland/prophet-core/solidity/interfaces/IModule.sol'; +import {IOracle} from '@defi-wonderland/prophet-core/solidity/interfaces/IOracle.sol'; +import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; + +import { + IAccessModule, + IWhitelistAccessModule, + WhitelistAccessModule +} from '../../../../contracts/examples/modules/access/WhitelistAccessModule.sol'; + +contract ForTest_WhitelistAccessModule is WhitelistAccessModule { + constructor(IOracle _oracle) WhitelistAccessModule(_oracle) {} + + function forTest_setSenderApproval(address _user, address _allowedSender, bool _status) public { + whitelist[_user][_allowedSender] = _status; + } +} + +/** + * @title Whitelist Access Module unit tests + */ +contract BaseTest is Test, Helpers { + // The target contract + ForTest_WhitelistAccessModule public whitelistAccessModule; + // A mock oracle + IOracle public oracle; + + event SetApproval(address _user, address _sender, bool _status); + + function setUp() public { + oracle = IOracle(makeAddr('Oracle')); + vm.etch(address(oracle), hex'069420'); + // + whitelistAccessModule = new ForTest_WhitelistAccessModule(oracle); + } +} + +contract WhitelistAccessModule_Unit_ModuleData is BaseTest { + function test_decodeAccessControlParameters_decodesSuccessfully(IAccessModule.AccessControlParameters memory _params) + public + view + { + // Test: decode the given access control parameters + IAccessModule.AccessControlParameters memory _decodedParams = + whitelistAccessModule.decodeAccessControlParameters(abi.encode(_params)); + + // Check: decoded values match original values? + assertEq(_decodedParams.sender, _params.sender); + assertEq(_decodedParams.typehash, _params.typehash); + assertEq(_decodedParams.typehashParams, _params.typehashParams); + assertEq(_decodedParams.accessControl.user, _params.accessControl.user); + assertEq(_decodedParams.accessControl.data, _params.accessControl.data); + } + + function test_moduleName_ReturnsCorrectName() public view { + assertEq(whitelistAccessModule.moduleName(), 'WhitelistAccessModule'); + } +} + +contract WhitelistAccessModule_Unit_HasAccess is BaseTest { + function test_hasAccess_authorizedSender(IAccessModule.AccessControlParameters memory _params) public { + // set _params.sender` as an allowed sender for `_params.accessControl.user` + whitelistAccessModule.forTest_setSenderApproval(_params.accessControl.user, _params.sender, true); + + assertTrue(whitelistAccessModule.hasAccess(abi.encode(_params))); + } + + function test_hasAccess_unauthorizedSender(IAccessModule.AccessControlParameters memory _params) public { + // set _params.sender` as an unallowed sender for `_params.accessControl.user` + whitelistAccessModule.forTest_setSenderApproval(_params.accessControl.user, _params.sender, false); + + assertFalse(whitelistAccessModule.hasAccess(abi.encode(_params))); + } + + /// @notice By default, authorization is denied + function test_hasAccess_unauthorizedByDefault(IAccessModule.AccessControlParameters memory _params) public { + assertFalse(whitelistAccessModule.hasAccess(abi.encode(_params))); + } +} + +contract WhitelistAccessModule_Unit_setSenderApproval is BaseTest { + function test_setSenderApproval_updatesState(address _user, address _sender, bool _status) public { + vm.prank(_user); + whitelistAccessModule.setSenderApproval(_sender, _status); + + assertEq(whitelistAccessModule.whitelist(_user, _sender), _status); + } + + function test_setSenderApproval_emitsEvent(address _user, address _sender, bool _status) public { + // Expect the event with correct parameters + vm.expectEmit(address(whitelistAccessModule)); + emit SetApproval(_user, _sender, _status); + + // Test: call setSenderApproval + vm.prank(_user); + whitelistAccessModule.setSenderApproval(_sender, _status); + } + + function test_setSenderApproval_CanUpdateStatus(address _user, address _sender, bool _status) public { + // Expect the event with correct parameters + vm.expectEmit(address(whitelistAccessModule)); + emit SetApproval(_user, _sender, _status); + + // sets `_status` for `_sender` + vm.prank(_user); + whitelistAccessModule.setSenderApproval(_sender, _status); + + vm.expectEmit(address(whitelistAccessModule)); + emit SetApproval(_user, _sender, !_status); + + // sets `!_status` for `_sender` + vm.prank(_user); + whitelistAccessModule.setSenderApproval(_sender, !_status); + } +}