Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor router logic update and tests #261

Merged
merged 3 commits into from
Dec 21, 2024
Merged
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
29 changes: 28 additions & 1 deletion contracts/Mock/MockERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,37 @@ pragma solidity 0.7.6;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MockERC20 is ERC20 {
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/drafts/IERC20Permit.sol";

contract MockERC20 is ERC20, IERC20Permit {
mapping(address => uint256) public override nonces;

constructor(address recipient, uint256 amount) ERC20("MockERC20", "MockERC20") {
ERC20._mint(recipient, amount);
}

// Hard-coded DOMAIN_SEPARATOR for testing purposes only.
// In a real implementation, this would be derived from EIP-712 parameters.
function DOMAIN_SEPARATOR() external pure override returns (bytes32) {
return 0x00;
}

function permit(
address owner,
address spender,
uint256 value,
uint256, // deadline - ignored in mock
uint8, // v - ignored in mock
bytes32, // r - ignored in mock
bytes32 // s - ignored in mock
) external override {
// For testing, ignore signature checks and deadline.
// Simply set allowance directly.
_approve(owner, spender, value);
// Increment nonce as if a successful permit was used.
nonces[owner]++;
}
}

contract MockBAL is ERC20 {
Expand Down
13 changes: 11 additions & 2 deletions contracts/Mock/MockGeyser.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,22 @@ contract MockGeyser {
});
}

event LogStaked(address vault, uint256 amount, bytes permission);
event Staked(address vault, uint256 amount, bytes permission);
event UnstakedAndClaimed(address vault, uint256 amount, bytes permission);

function stake(
address vault,
uint256 amount,
bytes calldata permission
) external {
emit LogStaked(vault, amount, permission);
emit Staked(vault, amount, permission);
}

function unstakeAndClaim(
address vault,
uint256 amount,
bytes calldata permission
) external {
emit UnstakedAndClaimed(vault, amount, permission);
}
}
2 changes: 1 addition & 1 deletion contracts/Mock/MockVaultFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract MockVaultFactory is ERC721("MockVaultFactory", "MVF") {
) external returns (address) {
uint256 vaultId = nextVaultId;
nextVaultId++;
_mint(msg.sender, vaultId);
ERC721._safeMint(msg.sender, vaultId);
return address(uint160(vaultId));
}
}
7 changes: 1 addition & 6 deletions contracts/Router/CharmGeyserRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,7 @@ contract CharmGeyserRouter is GeyserRouter {
bytes calldata permission,
LiqCreationPayload memory d
) external returns (address vault) {
// create vault
vault = create2Vault(vaultFactory, salt);

// transfer ownership
IERC721(vaultFactory).safeTransferFrom(address(this), vaultOwner, uint256(vault));

vault = create2Vault(vaultFactory, salt, vaultOwner);
// create liquidity and stake
createLiqAndStake(geyser, vault, permission, d);
}
Expand Down
45 changes: 21 additions & 24 deletions contracts/Router/GeyserRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@ contract GeyserRouter is IERC721Receiver {
return IERC721Receiver.onERC721Received.selector;
}

function create2Vault(address vaultFactory, bytes32 salt) public returns (address vault) {
function create2Vault(
address vaultFactory,
bytes32 salt,
address vaultOwner
) public returns (address vault) {
// create vault
vault = IFactory(vaultFactory).create2("", salt);
// transfer ownership
IERC721(vaultFactory).safeTransferFrom(address(this), vaultOwner, uint256(vault));
}

function depositStake(
Expand All @@ -48,10 +55,7 @@ contract GeyserRouter is IERC721Receiver {
bytes32 salt,
bytes calldata permission
) external returns (address vault) {
// create vault
vault = create2Vault(vaultFactory, salt);
// transfer ownership
IERC721(vaultFactory).safeTransferFrom(address(this), vaultOwner, uint256(vault));
vault = create2Vault(vaultFactory, salt, vaultOwner);
// transfer tokens and stake
depositStake(geyser, vault, amount, permission);
}
Expand Down Expand Up @@ -108,36 +112,29 @@ contract GeyserRouter is IERC721Receiver {
IGeyser(geyser).stake(vault, permit.value, permission);
}

struct StakeRequest {
struct GeyserAction {
address geyser;
address vault;
uint256 amount;
bytes permission;
}

function stakeMulti(StakeRequest[] calldata requests) external {
for (uint256 index = 0; index < requests.length; index++) {
StakeRequest calldata request = requests[index];
IGeyser(request.geyser).stake(request.vault, request.amount, request.permission);
function stakeMulti(GeyserAction[] calldata actions) external {
for (uint256 index = 0; index < actions.length; index++) {
GeyserAction calldata act = actions[index];
IGeyser(act.geyser).stake(act.vault, act.amount, act.permission);
}
}

struct UnstakeRequest {
address geyser;
address vault;
uint256 amount;
bytes permission;
}

function unstakeMulti(UnstakeRequest[] calldata requests) external {
for (uint256 index = 0; index < requests.length; index++) {
UnstakeRequest calldata request = requests[index];
IGeyser(request.geyser).unstakeAndClaim(request.vault, request.amount, request.permission);
function unstakeMulti(GeyserAction[] calldata actions) external {
for (uint256 index = 0; index < actions.length; index++) {
GeyserAction calldata act = actions[index];
IGeyser(act.geyser).unstakeAndClaim(act.vault, act.amount, act.permission);
}
}

function unstakeAndRestake(UnstakeRequest calldata r1, StakeRequest calldata r2) external {
IGeyser(r1.geyser).stake(r1.vault, r1.amount, r1.permission);
IGeyser(r2.geyser).unstakeAndClaim(r2.vault, r2.amount, r2.permission);
function unstakeAndRestake(GeyserAction calldata unstakeAct, GeyserAction calldata stakeAct) external {
IGeyser(unstakeAct.geyser).unstakeAndClaim(unstakeAct.vault, unstakeAct.amount, unstakeAct.permission);
IGeyser(stakeAct.geyser).stake(stakeAct.vault, stakeAct.amount, stakeAct.permission);
}
}
12 changes: 10 additions & 2 deletions frontend/src/sdk/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ export const approveCreateDepositStake = async (geyserAddress: string, amount: B
const token = new Contract(tokenAddress, ERC20_ABI, signer)

const salt = randomBytes(32)
const vaultAddress = await router.callStatic.create2Vault(config.VaultFactory.address, salt)
const vaultAddress = await router.callStatic.create2Vault(
config.VaultFactory.address,
salt,
await signer.getAddress(),
)
const vault = new Contract(vaultAddress, config.VaultTemplate.abi, signer)
const lockPermission = await signPermission('Lock', vault, signer, geyserAddress, token.address, amount, '0')
const args = [geyserAddress, config.VaultFactory.address, await signer.getAddress(), amount, salt, lockPermission]
Expand Down Expand Up @@ -186,7 +190,11 @@ export const permitCreateDepositStake = async (geyserAddress: string, amount: Bi
}

const salt = randomBytes(32)
const vaultAddress = await router.callStatic.create2Vault(config.VaultFactory.address, salt)
const vaultAddress = await router.callStatic.create2Vault(
config.VaultFactory.address,
salt,
await signer.getAddress(),
)
const vault = new Contract(vaultAddress, config.VaultTemplate.address, signer)

const permit = await signPermitEIP2612(signer, tokenAddress, router.address, amount, deadline)
Expand Down
6 changes: 3 additions & 3 deletions test/CharmGeyserRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('CharmGeyserRouter', function () {
}

await expect(router.connect(user).createLiqAndStake(geyser.address, vault, '0x', liqPayload))
.to.emit(geyser, 'LogStaked')
.to.emit(geyser, 'Staked')
.withArgs(vault, token0Amount.add(token1Amount), '0x')

// After staking, router should have transferred all tokens out
Expand Down Expand Up @@ -98,7 +98,7 @@ describe('CharmGeyserRouter', function () {
const args = [geyser.address, vaultFactory.address, await vaultOwner.getAddress(), salt, '0x', liqPayload]
const vault = await router.connect(user).callStatic.create2VaultCreateLiqAndStake(...args)
await expect(router.connect(user).create2VaultCreateLiqAndStake(...args))
.to.emit(geyser, 'LogStaked')
.to.emit(geyser, 'Staked')
.withArgs(vault, token0Amount.add(token1Amount), '0x')
expect(await vaultFactory.ownerOf(1)).to.equal(await vaultOwner.getAddress())
})
Expand Down Expand Up @@ -145,7 +145,7 @@ describe('CharmGeyserRouter', function () {
}

await expect(router.connect(user).createLiqAndStake(geyser.address, vault, '0x', liqPayload))
.to.emit(geyser, 'LogStaked')
.to.emit(geyser, 'Staked')
.withArgs(vault, 0, '0x')
})
})
Expand Down
Loading
Loading