Skip to content

Commit

Permalink
Add pool funder
Browse files Browse the repository at this point in the history
  • Loading branch information
danhper committed Oct 28, 2024
1 parent 2ef5972 commit cab1542
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/PoolFunder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import {Address} from "oz/utils/Address.sol";
import {IERC20} from "oz/token/ERC20/IERC20.sol";

interface BalancerV2Vault {
enum JoinKind {
INIT,
EXACT_TOKENS_IN_FOR_BPT_OUT,
TOKEN_IN_FOR_EXACT_BPT_OUT,
ALL_TOKENS_IN_FOR_EXACT_BPT_OUT
}

struct JoinPoolRequest {
address[] assets;
uint256[] maxAmountsIn;
bytes userData;
bool fromInternalBalance;
}

function joinPool(
bytes32 poolId,
address sender,
address recipient,
JoinPoolRequest calldata request
) external;

function getPoolTokens(bytes32 poolId)
external
view
returns (address[] memory, uint256[] memory, uint256);
}

interface Pool {
function getPoolId() external view returns (bytes32);
}

contract PoolFunder {
using Address for address;

BalancerV2Vault public immutable vault;
address public immutable factory;
address public immutable gyd;

constructor(address vault_, address gyd_, address factory_) {
gyd = gyd_;
vault = BalancerV2Vault(vault_);
factory = factory_;
}

function fundPool(uint256 gydAmount, bytes calldata creationData) external {
bytes memory result = factory.functionCall(creationData);
address pool = abi.decode(result, (address));
bytes32 poolId = Pool(pool).getPoolId();
(address[] memory assets,,) = vault.getPoolTokens(poolId);
uint256[] memory maxAmountsIn = new uint256[](assets.length);

for (uint256 i = 0; i < assets.length; i++) {
if (assets[i] == gyd) {
maxAmountsIn[i] = gydAmount;
IERC20(gyd).approve(address(vault), gydAmount);
break;
}
}

bytes memory userData =
abi.encode(BalancerV2Vault.JoinKind.INIT, maxAmountsIn);
vault.joinPool(
poolId,
address(this),
address(this),
BalancerV2Vault.JoinPoolRequest({
assets: assets,
maxAmountsIn: maxAmountsIn,
userData: userData,
fromInternalBalance: false
})
);
}
}
43 changes: 43 additions & 0 deletions test/PoolFunder.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.24;

import {Test, stdStorage, StdStorage} from "forge-std/Test.sol";

import {IERC20} from "oz/token/ERC20/IERC20.sol";

import {PoolFunder} from "../src/PoolFunder.sol";

contract PoolFunderTest is Test {
using stdStorage for StdStorage;

address public constant BALANCER_VAULT_ADDRSS =
0xBA12222222228d8Ba445958a75a0704d566BF2C8;
address public constant GYD_ADDRESS =
0xCA5d8F8a8d49439357d3CF46Ca2e720702F132b8;
address public constant ECLP_FACTORY =
0x5d3Be8aaE57bf0D1986Ff7766cC9607B6cC99b89;
bytes public poolCreationData =
hex"f680d973000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000ddb6275b03a40000000000000000000000000000000000000000000000000000de60af19e8dc00000000000000000000000000000000000000000000000000009d025defee4df4400000000000000000000000000000000000000000000000009d025defee4df440000000000000000000000000000000000000000000000d8d726b7177a800000ffffffffffffffffffffffffffffffffb89fa781a6bdbb939ac23e7f4013781b0000000000000000000000000000000017c636bc012fc7792e9b6af84d947b0100000000000000000000000000000000475d9ae35c93e935276528c1b97cc17e0000000000000000000000000000000017ce6f8cfefd33b4196881f8170708fe00000000000000000000000000000000475ef9b0daeb16caf1a74b67152bbc940000000000000000000000000000000017ca532480167d94b273ea6507b104ec0000000000000000000000000000000000041c687ee6b61d751091434b89e119fffffffffffffffffffffffffffffffffffea13281a8d26461305c5f3f76c1d0000000000000000000000000000000004b3b4ca85a86c473e421ffd60063dc80000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000efde1c764df6522a068b38106563de166ac97f5800000000000000000000000033acca8f9a9592a9a97604e597649b24f5fca665000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000997c49a9ce8b6c6277719750641874943024e05c0000000000000000000000000000000000000000000000000000000012cc03000000000000000000000000000000000000000000000000000000000000278d00000000000000000000000000000000000000000000000000000000000000001a4779726f73636f70652045434c50204759442f41555344432e65000000000000000000000000000000000000000000000000000000000000000000000000001045434c502d4759442d41555344432e65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000ca5d8f8a8d49439357d3cf46ca2e720702f132b8000000000000000000000000f0e7ec247b918311afa054e0aedb99d74c31b809000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f62fd24941b585b91eb059e0ea1a7e729357511";

PoolFunder public funder;

function setUp() public {
vm.createSelectFork("gnosis", 36_732_356);
funder = new PoolFunder(BALANCER_VAULT_ADDRSS, GYD_ADDRESS, ECLP_FACTORY);
}

function testFundPool() public {
uint256 amount = 1_000_000e18;
_mintTokensFor(GYD_ADDRESS, address(funder), amount);

funder.fundPool(amount, poolCreationData);
}

function _mintTokensFor(address token_, address account_, uint256 amount_)
internal
{
stdstore.target(token_).sig(IERC20(token_).balanceOf.selector).with_key(
account_
).checked_write(amount_);
}
}

0 comments on commit cab1542

Please sign in to comment.