Skip to content

Commit

Permalink
feat: add yield switching with signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
0xChin committed Nov 6, 2024
1 parent c0c6448 commit 6818bba
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
16 changes: 16 additions & 0 deletions src/contracts/Grateful.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity 0.8.26;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
Expand All @@ -21,6 +22,7 @@ import {AaveV3ERC4626, IPool} from "yield-daddy/aave-v3/AaveV3ERC4626.sol";
contract Grateful is IGrateful, Ownable2Step {
using Bytes32AddressLib for bytes32;
using SafeERC20 for IERC20;
using ECDSA for bytes32;

/*//////////////////////////////////////////////////////////////
STATE VARIABLES
Expand All @@ -29,6 +31,9 @@ contract Grateful is IGrateful, Ownable2Step {
/// @inheritdoc IGrateful
IPool public aavePool;

/// @inheritdoc IGrateful
string public constant SWITCH_YIELD_MESSAGE = unicode"🐧 At Grateful, we love penguins 🐧";

Check warning on line 35 in src/contracts/Grateful.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Function order is incorrect, contract constant declaration can not go after state variable declaration (line 32)

/// @inheritdoc IGrateful
mapping(address => bool) public tokensWhitelisted;

Expand Down Expand Up @@ -350,6 +355,17 @@ contract Grateful is IGrateful, Ownable2Step {
yieldingFunds[msg.sender] = !yieldingFunds[msg.sender];
}

/// @inheritdoc IGrateful
function switchYieldingFundsWithSig(bytes calldata _signature, address _merchant) external {
// TODO: Nonce pls
bytes32 signedMessageHash = keccak256(abi.encode(SWITCH_YIELD_MESSAGE));

if (signedMessageHash.recover(_signature) != _merchant) {
revert Grateful_InvalidSignature();
}
yieldingFunds[_merchant] = !yieldingFunds[_merchant];
}

/// @inheritdoc IGrateful
function setFee(
uint256 _newFee
Expand Down
11 changes: 11 additions & 0 deletions src/interfaces/IGrateful.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,19 @@ interface IGrateful {
/// @notice Thrown when the user tries to withdraw more shares than they have.
error Grateful_WithdrawExceedsShares();

/// @notice Thrown when the signature is not valid.
error Grateful_InvalidSignature();

/*///////////////////////////////////////////////////////////////
VARIABLES
//////////////////////////////////////////////////////////////*/

/// @notice Returns the owner of the contract.
function owner() external view returns (address);

/// @notice Returns the message to sign to switch yield with signature
function SWITCH_YIELD_MESSAGE() external view returns (string memory);

/// @notice Aave pool for yielding merchants' funds.
function aavePool() external view returns (IPool);

Expand Down Expand Up @@ -342,6 +348,11 @@ interface IGrateful {
*/
function switchYieldingFunds() external;

/**
* @notice Toggles the merchant's preference to yield funds using a signature.
*/
function switchYieldingFundsWithSig(bytes calldata _signature, address _merchant) external;

/**
* @notice Calculates the ID of a payment.
* @param _sender Address of the sender.
Expand Down
12 changes: 12 additions & 0 deletions test/integration/Grateful.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
pragma solidity 0.8.26;

import {OneTime} from "contracts/OneTime.sol";

import {console} from "forge-std/console.sol";

Check warning on line 6 in test/integration/Grateful.t.sol

View workflow job for this annotation

GitHub Actions / Lint Commit Messages

Variable "console" is unused
import {IntegrationBase} from "test/integration/IntegrationBase.sol";

contract IntegrationGreeter is IntegrationBase {
Expand Down Expand Up @@ -268,4 +270,14 @@ contract IntegrationGreeter is IntegrationBase {
uint256 feeAmount = _AMOUNT_USDC - amountAfterFee;
assertEq(_usdc.balanceOf(_owner), feeAmount);
}

function test_SwitchYieldingFundsWithSig() public {
string memory message = _grateful.SWITCH_YIELD_MESSAGE();

(uint8 v, bytes32 r, bytes32 s) = vm.sign(_userPk, keccak256(abi.encode(message)));

bytes memory signature = abi.encodePacked(r, s, v);

_grateful.switchYieldingFundsWithSig(signature, _user);
}
}
3 changes: 2 additions & 1 deletion test/integration/IntegrationBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ contract IntegrationBase is Test {
uint256 internal constant _FEE = 100;

// EOAs
address internal _user = makeAddr("user");
uint256 internal _userPk = 0x4f9f153352796ab5f555d215a5cba1c2b0daef31de556ab65c522435fb23373c;
address internal _user = vm.addr(_userPk);
address internal _merchant = makeAddr("merchant");
address internal _owner = makeAddr("owner");
address internal _gratefulAutomation = makeAddr("gratefulAutomation");
Expand Down

0 comments on commit 6818bba

Please sign in to comment.