diff --git a/src/diamonds/nayms/libs/LibEntity.sol b/src/diamonds/nayms/libs/LibEntity.sol index 82a348e5..b05d9bbc 100644 --- a/src/diamonds/nayms/libs/LibEntity.sol +++ b/src/diamonds/nayms/libs/LibEntity.sol @@ -143,13 +143,18 @@ library LibEntity { } if (LibObject._getParentFromAddress(signer) != _stakeholders.entityIds[i]) { - revert SimplePolicyStakeholderSignatureInvalid( - signingHash, - _stakeholders.signatures[i], - LibHelpers._getIdForAddress(signer), - LibObject._getParentFromAddress(signer), - _stakeholders.entityIds[i] - ); + // default implementation didn't match the signer + signer = getSignerLedgerFallback(signingHash, _stakeholders.signatures[i]); // fallback ledger implementation + + if (LibObject._getParentFromAddress(signer) != _stakeholders.entityIds[i]) { + revert SimplePolicyStakeholderSignatureInvalid( + signingHash, + _stakeholders.signatures[i], + LibHelpers._getIdForAddress(signer), + LibObject._getParentFromAddress(signer), + _stakeholders.entityIds[i] + ); + } } LibACL._assignRole(_stakeholders.entityIds[i], _policyId, _stakeholders.roles[i]); } @@ -158,6 +163,38 @@ library LibEntity { emit SimplePolicyCreated(_policyId, _entityId); } + function getSignerLedgerFallback(bytes32 signingHash, bytes memory signature) private returns (address) { + bytes32 r; + bytes32 s; + uint8 v; + + // ecrecover takes the signature parameters, and the only way to get them + if (signature.length == 65) { + // currently is to use assembly. + /// @solidity memory-safe-assembly + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + v = _adjustV(v); + } + + (address signer, ) = ECDSA.tryRecover(ECDSA.toEthSignedMessageHash(signingHash), v, r, s); + + return signer; + } + + function _adjustV(uint8 v) private returns (uint8) { + if (v == 0) { + return 27; + } else if (v == 1) { + return 28; + } else { + return v; + } + } + /// @param _amount the amount of entity token that is minted and put on sale /// @param _totalPrice the buy amount function _startTokenSale( diff --git a/test/T05TokenWrapper.t.sol b/test/T05TokenWrapper.t.sol index 0b5e7597..ad820c47 100644 --- a/test/T05TokenWrapper.t.sol +++ b/test/T05TokenWrapper.t.sol @@ -100,7 +100,7 @@ contract T05TokenWrapper is D03ProtocolDefaults { vm.startPrank(signer1); wrapper.increaseAllowance(account0, type(uint256).max); assertEq(wrapper.allowance(signer1, account0), type(uint256).max, "allowance should have increased"); - + vm.expectRevert("ERC20: allowance overflow"); wrapper.increaseAllowance(account0, 1); vm.stopPrank(); @@ -108,11 +108,10 @@ contract T05TokenWrapper is D03ProtocolDefaults { vm.startPrank(signer1); wrapper.decreaseAllowance(account0, type(uint256).max); assertEq(wrapper.allowance(signer1, account0), 0, "allowance should have decreased"); - + vm.expectRevert("ERC20: decreased allowance below zero"); wrapper.decreaseAllowance(account0, 1); vm.stopPrank(); - } function testPermit() public {