Skip to content

Commit

Permalink
Transpile e4435eed
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Jul 27, 2023
1 parent 231affb commit 1c13b81
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-guests-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': patch
---

`ERC2771Context`: Prevent revert in `_msgData()` when a call originating from a trusted forwarder is not long enough to contain the request signer address (i.e. `msg.data.length` is less than 20 bytes). Return the full calldata in that case.
2 changes: 1 addition & 1 deletion contracts/metatx/ERC2771ContextUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ abstract contract ERC2771ContextUpgradeable is Initializable, ContextUpgradeable
}

function _msgData() internal view virtual override returns (bytes calldata) {
if (isTrustedForwarder(msg.sender)) {
if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {
return msg.data[:msg.data.length - 20];
} else {
return super._msgData();
Expand Down
6 changes: 6 additions & 0 deletions contracts/mocks/ContextMockUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ contract ContextMockUpgradeable is Initializable, ContextUpgradeable {
emit Data(_msgData(), integerValue, stringValue);
}

event DataShort(bytes data);

function msgDataShort() public {
emit DataShort(_msgData());
}

/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
Expand Down
18 changes: 14 additions & 4 deletions test/metatx/ERC2771Context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ContextMockCaller = artifacts.require('ContextMockCaller');
const { shouldBehaveLikeRegularContext } = require('../utils/Context.behavior');

contract('ERC2771Context', function (accounts) {
const [, anotherAccount] = accounts;
const [, trustedForwarder] = accounts;

beforeEach(async function () {
this.forwarder = await MinimalForwarder.new();
Expand Down Expand Up @@ -78,11 +78,11 @@ contract('ERC2771Context', function (accounts) {

it('returns the original sender when calldata length is less than 20 bytes (address length)', async function () {
// The forwarder doesn't produce calls with calldata length less than 20 bytes
const recipient = await ERC2771ContextMock.new(anotherAccount);
const recipient = await ERC2771ContextMock.new(trustedForwarder);

const { receipt } = await recipient.msgSender({ from: anotherAccount });
const { receipt } = await recipient.msgSender({ from: trustedForwarder });

await expectEvent(receipt, 'Sender', { sender: anotherAccount });
await expectEvent(receipt, 'Sender', { sender: trustedForwarder });
});
});

Expand All @@ -108,5 +108,15 @@ contract('ERC2771Context', function (accounts) {
await expectEvent.inTransaction(tx, ERC2771ContextMock, 'Data', { data, integerValue, stringValue });
});
});

it('returns the full original data when calldata length is less than 20 bytes (address length)', async function () {
// The forwarder doesn't produce calls with calldata length less than 20 bytes
const recipient = await ERC2771ContextMock.new(trustedForwarder);

const { receipt } = await recipient.msgDataShort({ from: trustedForwarder });

const data = recipient.contract.methods.msgDataShort().encodeABI();
await expectEvent(receipt, 'DataShort', { data });
});
});
});

0 comments on commit 1c13b81

Please sign in to comment.