MUST support a redeem flow where the Principal Tokens are burned from holder directly where holder is msg.sender or msg.sender has EIP-20 approval over the principal tokens of holder.

MUST support a withdraw flow where the principal tokens are burned from holder directly where holder is msg.sender or msg.sender has EIP-20 approval over the principal tokens of holder.
    //copy-paste into `PrincipalToken.sol`
    function testRedeemDoesNotSupportERC20ApprovalFlow() public {
        uint256 amountToDeposit = 1e18;
        uint256 expected = _testDeposit(amountToDeposit, address(this));
        _increaseTimeToExpiry();
        principalToken.storeRatesAtExpiry();

        principalToken.approve(MOCK_ADDR_5, UINT256_MAX);
        assertEq(principalToken.allowance(address(this), MOCK_ADDR_5), UINT256_MAX);

        vm.startPrank(MOCK_ADDR_5);
        vm.expectRevert();
        //Should not revert as MOCK_ADDR_5 has allowance over tokens.
        principalToken.redeem(expected, MOCK_ADDR_5, address(this));
        vm.stopPrank();
    }
    
    function testWithdrawDoesNotSupportERC20ApprovalFlow() public {
        uint256 amount = 1e18;
        underlying.approve(address(principalToken), amount);
        principalToken.deposit(amount, testUser);

        principalToken.approve(MOCK_ADDR_5, UINT256_MAX);
        assertEq(principalToken.allowance(address(this), MOCK_ADDR_5), UINT256_MAX);

        vm.prank(MOCK_ADDR_5);
        vm.expectRevert();
        //Should not revert as MOCK_ADDR_5 has allowance over tokens.
        principalToken.withdraw(amount, MOCK_ADDR_5, testUser);

        vm.stopPrank();
    }
MUST factor in both global and user-specific limits, like if withdrawals are entirely disabled (even temporarily) it MUST return 0.

MUST NOT revert.
   //copy-paste into `PrincipalToken.sol`
   function testMaxWithdrawRevertsWhenPausedWhenItShouldNeverRevert() public {
        vm.prank(scriptAdmin);
        principalToken.pause();

        vm.expectRevert();
        //Should not revert, should return 0 to comply to ERC-5095.
        principalToken.maxWithdraw(address(this));
    }
MUST factor in both global and user-specific limits, like if redemption is entirely disabled (even temporarily) it MUST return 0.
    //copy-paste into `PrincipalToken.sol`
    function testMaxRedeemDoesNotReturnZeroWhenPausedEvenThoughItShould() public {
        uint256 amountToDeposit = 1e18;
        _testDeposit(amountToDeposit, address(this));

        vm.prank(scriptAdmin);
        principalToken.pause();

        //Should return 0 to comply to ERC-5095.
        assertNotEq(principalToken.maxRedeem(address(this)), 0);
    }
