Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/Recibo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ contract Recibo is ReciboEvents {
function sendMsg(
ReciboInfo calldata info
) public {
require(info.messageFrom == msg.sender, "Recibo: messageFrom must match sender");
emit SentMsg(msg.sender, info.messageFrom, info.messageTo);
}

Expand All @@ -67,6 +68,7 @@ contract Recibo is ReciboEvents {
uint256 value,
ReciboInfo calldata info
) public returns (bool) {
require(info.messageFrom == msg.sender, "Recibo: messageFrom must match sender");
emit TransferWithMsg(msg.sender, to, info.messageFrom, info.messageTo, value);
return _token.transferFrom(msg.sender, to, value);
}
Expand Down Expand Up @@ -94,7 +96,9 @@ contract Recibo is ReciboEvents {
bytes32 s,
ReciboInfo calldata info
) public {
require(owner != address(this));
require(owner != address(this), "Recibo: owner cannot be this contract");
require(spender != address(this), "Recibo: spender cannot be this contract");
require(info.messageFrom == owner, "Recibo: messageFrom must match owner");
emit ApproveWithMsg(owner, spender, info.messageFrom, info.messageTo, value);
_token.permit(owner, spender, value, deadline, v, r, s);
}
Expand All @@ -121,6 +125,7 @@ contract Recibo is ReciboEvents {
bytes32 s,
ReciboInfo calldata info
) public returns (bool) {
require(info.messageFrom == msg.sender, "Recibo: messageFrom must match sender");
emit TransferWithMsg(msg.sender, to, info.messageFrom, info.messageTo, value);
_token.permit(msg.sender, address(this), value, deadline, v, r, s);
return _token.transferFrom(msg.sender, to, value);
Expand Down Expand Up @@ -148,6 +153,7 @@ contract Recibo is ReciboEvents {
bytes memory signature,
ReciboInfo calldata info
) public {
require(info.messageFrom == from, "Recibo: messageFrom must match from");
emit TransferWithMsg(from, to, info.messageFrom, info.messageTo, value);
_token.transferWithAuthorization(from, to, value, validAfter, validBefore, nonce, signature);
}
Expand Down
3 changes: 3 additions & 0 deletions src/ReciboToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ contract ReciboToken is ERC20, ReciboEvents {
* @dev See {ERC20-transfer}.
*/
function transferWithMsg(address to, uint256 value, address messageFrom, address messageTo, string calldata metadata, bytes calldata message) public returns (bool) {
require(messageFrom == msg.sender, "ReciboToken: messageFrom must match sender");
emit TransferWithMsg(msg.sender, to, messageFrom, messageTo, value);
return transfer(to, value);
}
Expand All @@ -51,6 +52,7 @@ contract ReciboToken is ERC20, ReciboEvents {
* @dev See {ERC20-approve}.
*/
function approveWithMsg(address spender, uint256 value, address messageFrom, address messageTo, string calldata metadata, bytes calldata message) public returns (bool) {
require(messageFrom == msg.sender, "ReciboToken: messageFrom must match sender");
emit ApproveWithMsg(msg.sender, spender, messageFrom, messageTo, value);
return approve(spender, value);
}
Expand All @@ -60,6 +62,7 @@ contract ReciboToken is ERC20, ReciboEvents {
* @dev See {ERC20-transferFrom}.
*/
function transferFromWithMsg(address from, address to, uint256 value, address messageFrom, address messageTo, string calldata metadata, bytes calldata message) public returns (bool) {
require(messageFrom == from, "ReciboToken: messageFrom must match from");
emit TransferWithMsg(from, to, messageFrom, messageTo, value);
return transferFrom(from, to, value);
}
Expand Down
13 changes: 10 additions & 3 deletions test/Recibo.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ contract ReciboExtensionTest is GaslessTestBase {
address private minter;
uint256 private minterKey;
bytes private msgBytes = abi.encode("message");
Recibo.ReciboInfo private info = Recibo.ReciboInfo(minter, user, "metadata", msgBytes);
Recibo.ReciboInfo private info;

uint private deadline;
uint256 private validBefore;
uint256 private validAfter;

function setUp() public {
(minter, minterKey) = makeAddrAndKey("minter");
info = Recibo.ReciboInfo(minter, user, "metadata", msgBytes);

vm.startPrank(minter);
token = new GaslessToken("Token", "TKN", 200);
Expand All @@ -52,9 +53,12 @@ contract ReciboExtensionTest is GaslessTestBase {


function test_sendMsg() public {
// Need to call from minter since info.messageFrom == minter
vm.startPrank(minter);
vm.expectEmit(true, true, true, true);
emit ReciboEvents.SentMsg(address(this), info.messageFrom, info.messageTo);
emit ReciboEvents.SentMsg(minter, info.messageFrom, info.messageTo);
recibo.sendMsg(info);
vm.stopPrank();
}

function test_transferWithMsg() public {
Expand Down Expand Up @@ -92,10 +96,13 @@ contract ReciboExtensionTest is GaslessTestBase {
bytes32 permit = buildPermitMessage(minter, address(recibo), 40, deadline, token);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(minterKey, permit);

// Create info with user as messageFrom to pass validation
Recibo.ReciboInfo memory userInfo = Recibo.ReciboInfo(user, user, "metadata", msgBytes);

vm.startPrank(user);
address fakeSigner = 0x4816Daec8E87b4ebCd4f44e6A16c7019aeFA1150;
vm.expectRevert(abi.encodeWithSelector(ERC20Permit.ERC2612InvalidSigner.selector, fakeSigner, user));
recibo.permitAndTransferFromWithMsg(user, value, deadline, v, r, s, info);
recibo.permitAndTransferFromWithMsg(user, value, deadline, v, r, s, userInfo);
vm.stopPrank();
}

Expand Down
3 changes: 2 additions & 1 deletion test/ReciboGasTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ contract ReciboGasTest is GaslessTestBase, BigMsg {
address private minter;
uint256 private minterKey;
bytes private msgBytes = abi.encode("message");
Recibo.ReciboInfo private info = Recibo.ReciboInfo(minter, user, "metadata", msgBytes);
Recibo.ReciboInfo private info;

uint private deadline;
uint256 private validBefore;
uint256 private validAfter;

function setUp() public {
(minter, minterKey) = makeAddrAndKey("minter");
info = Recibo.ReciboInfo(minter, user, "metadata", msgBytes);
deadline = makeDeadline(10);
(validAfter, validBefore) = makeValidTime(100);

Expand Down