diff --git a/contracts/test/helpers/MockChainlinkAggregator.sol b/contracts/test/helpers/MockChainlinkAggregator.sol index d479db5..280438f 100644 --- a/contracts/test/helpers/MockChainlinkAggregator.sol +++ b/contracts/test/helpers/MockChainlinkAggregator.sol @@ -83,14 +83,14 @@ contract MockChainlinkOracleAggregator is Ownable, IOracleAggregator { */ function getTokenValueOfOneNativeToken( address token - ) external view virtual returns (uint256 exchangeRate) { + ) external view virtual returns (uint128 exchangeRate) { // we'd actually want eth / token uint256 tokenPriceUnadjusted = _getTokenPrice(token); uint8 _tokenOracleDecimals = tokensInfo[token].decimals; exchangeRate = - ((10 ** _tokenOracleDecimals) * + uint128(((10 ** _tokenOracleDecimals) * (10 ** IERC20Metadata(token).decimals())) / - tokenPriceUnadjusted; + tokenPriceUnadjusted); } // Making explicit revert or make use of stale price feed which reverts diff --git a/contracts/token/BiconomyTokenPaymaster.sol b/contracts/token/BiconomyTokenPaymaster.sol index 18b7024..9f694b1 100644 --- a/contracts/token/BiconomyTokenPaymaster.sol +++ b/contracts/token/BiconomyTokenPaymaster.sol @@ -73,11 +73,11 @@ contract BiconomyTokenPaymaster is // receiver of withdrawn fee tokens address public feeReceiver; - // paymasterAndData: concat of [paymasterAddress(address), priceSource(enum 1 byte), abi.encode(validUntil, validAfter, feeToken, exchangeRate, priceMarkup): makes up 32*5 bytes, signature] + // paymasterAndData: concat of [paymasterAddress(address), priceSource(enum 1 byte), validUntil(6 byte), validAfter(6 byte), feeToken(20 bytes), exchangeRate(16 bytes), priceMarkup(4 bytes), signature] // PND offset is used to indicate offsets to decode, used along with Signature offset uint256 private constant VALID_PND_OFFSET = 21; - uint256 private constant SIGNATURE_OFFSET = 181; + uint256 private constant SIGNATURE_OFFSET = 73; /** * Designed to enable the community to track change in storage variable UNACCOUNTED_COST which is used @@ -116,7 +116,7 @@ contract BiconomyTokenPaymaster is uint256 indexed totalCharge, uint32 priceMarkup, bytes32 userOpHash, - uint256 exchangeRate, + uint128 exchangeRate, ExchangeRateSource priceSource ); @@ -340,7 +340,7 @@ contract BiconomyTokenPaymaster is uint48 validUntil, uint48 validAfter, address feeToken, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup ) public view returns (bytes32) { //can't use userOp.hash(), since it contains also the paymasterAndData itself. @@ -378,7 +378,7 @@ contract BiconomyTokenPaymaster is uint48 validUntil, uint48 validAfter, address feeToken, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup, bytes calldata signature ) @@ -393,16 +393,11 @@ contract BiconomyTokenPaymaster is bytes1(paymasterAndData[VALID_PND_OFFSET - 1:VALID_PND_OFFSET]) ) ); - ( - validUntil, - validAfter, - feeToken, - exchangeRate, - priceMarkup - ) = abi.decode( - paymasterAndData[VALID_PND_OFFSET:SIGNATURE_OFFSET], - (uint48, uint48, address, uint256, uint32) - ); + validUntil = uint48(bytes6(paymasterAndData[21:27])); + validAfter = uint48(bytes6(paymasterAndData[27:33])); + feeToken = address(bytes20(paymasterAndData[33:53])); + exchangeRate = uint128(bytes16(paymasterAndData[53:69])); + priceMarkup = uint32(bytes4(paymasterAndData[69:73])); signature = paymasterAndData[SIGNATURE_OFFSET:]; } @@ -447,7 +442,7 @@ contract BiconomyTokenPaymaster is uint48 validUntil, uint48 validAfter, address feeToken, - uint256 exchangeRate, + uint128 exchangeRate, uint32 priceMarkup, bytes calldata signature ) = parsePaymasterAndData(userOp.paymasterAndData); @@ -520,7 +515,7 @@ contract BiconomyTokenPaymaster is address account; IERC20 feeToken; ExchangeRateSource priceSource; - uint256 exchangeRate; + uint128 exchangeRate; uint32 priceMarkup; bytes32 userOpHash; assembly ("memory-safe") { @@ -544,7 +539,7 @@ contract BiconomyTokenPaymaster is userOpHash := calldataload(offset) } - uint256 effectiveExchangeRate = exchangeRate; + uint128 effectiveExchangeRate = exchangeRate; if ( priceSource == ExchangeRateSource.ORACLE_BASED diff --git a/contracts/token/oracles/ChainlinkOracleAggregator.sol b/contracts/token/oracles/ChainlinkOracleAggregator.sol index 0b0829e..4fcaa9e 100644 --- a/contracts/token/oracles/ChainlinkOracleAggregator.sol +++ b/contracts/token/oracles/ChainlinkOracleAggregator.sol @@ -80,15 +80,15 @@ contract ChainlinkOracleAggregator is Ownable, IOracleAggregator { */ function getTokenValueOfOneNativeToken( address token - ) external view virtual returns (uint256 exchangeRate) { + ) external view virtual returns (uint128 exchangeRate) { // we'd actually want eth / token ( uint256 tokenPrice, uint8 tokenOracleDecimals ) = _getTokenPriceAndDecimals(token); exchangeRate = - 10 ** (tokenOracleDecimals + IERC20Metadata(token).decimals()) / - tokenPrice; + uint128(10 ** (tokenOracleDecimals + IERC20Metadata(token).decimals()) / + tokenPrice); } function _getTokenPriceAndDecimals( diff --git a/contracts/token/oracles/IOracleAggregator.sol b/contracts/token/oracles/IOracleAggregator.sol index e3492b6..c0a7bc7 100644 --- a/contracts/token/oracles/IOracleAggregator.sol +++ b/contracts/token/oracles/IOracleAggregator.sol @@ -4,5 +4,5 @@ pragma solidity ^0.8.20; interface IOracleAggregator { function getTokenValueOfOneNativeToken( address _token - ) external view returns (uint256 exchangeRate); + ) external view returns (uint128 exchangeRate); } diff --git a/contracts/token/oracles/OracleAggregator.sol b/contracts/token/oracles/OracleAggregator.sol index a545363..9a85463 100644 --- a/contracts/token/oracles/OracleAggregator.sol +++ b/contracts/token/oracles/OracleAggregator.sol @@ -55,7 +55,7 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { */ function getTokenValueOfOneNativeToken( address token - ) public view returns (uint256 exchangeRate) { + ) public view returns (uint128 exchangeRate) { // we'd actually want eth / token ( uint256 tokenPrice, @@ -63,8 +63,8 @@ abstract contract OracleAggregator is Ownable, IOracleAggregator { uint8 tokenDecimals ) = _getTokenPriceAndDecimals(token); exchangeRate = - 10 ** (tokenOracleDecimals + tokenDecimals) / - tokenPrice; + uint128(10 ** (tokenOracleDecimals + tokenDecimals) / + tokenPrice); } function _getTokenPriceAndDecimals( diff --git a/test/foundry/token-paymaster/TokenPaymaster.t.sol b/test/foundry/token-paymaster/TokenPaymaster.t.sol index eb50468..bf6ffc1 100644 --- a/test/foundry/token-paymaster/TokenPaymaster.t.sol +++ b/test/foundry/token-paymaster/TokenPaymaster.t.sol @@ -195,7 +195,7 @@ contract TokenPaymasterTest is SATestBase { .ORACLE_BASED; uint48 validUntil = 3735928559; uint48 validAfter = 4660; - uint256 exchangeRate = 977100; + uint128 exchangeRate = 977100; uint32 priceMarkup = 1100000; op.paymasterAndData = abi.encodePacked( @@ -302,7 +302,7 @@ contract TokenPaymasterTest is SATestBase { .ORACLE_BASED; uint48 validUntil = 3735928559; uint48 validAfter = 4660; - uint256 exchangeRate = 977100; + uint128 exchangeRate = 977100; uint32 priceMarkup = 1100000; op.paymasterAndData = abi.encodePacked( @@ -352,7 +352,7 @@ contract TokenPaymasterTest is SATestBase { .ORACLE_BASED; uint48 validUntil = 3735928559; uint48 validAfter = 4660; - uint256 exchangeRate = 977100; + uint128 exchangeRate = 977100; uint32 priceMarkup = 1100000; op.paymasterAndData = abi.encodePacked( @@ -397,7 +397,7 @@ contract TokenPaymasterTest is SATestBase { .ORACLE_BASED; uint48 validUntil = 3735928559; uint48 validAfter = 4660; - uint256 exchangeRate = 977100; + uint128 exchangeRate = 977100; uint32 priceMarkup = 2200000; bytes32 hash = _btpm.getHash( @@ -451,7 +451,7 @@ contract TokenPaymasterTest is SATestBase { .ORACLE_BASED; uint48 validUntil = 3735928559; uint48 validAfter = 4660; - uint256 exchangeRate = 977100; + uint128 exchangeRate = 977100; uint32 priceMarkup = 1100000; bytes32 hash = _btpm.getHash(