Skip to content

Commit

Permalink
naive implementation for proportionally addding liquidity
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Aug 27, 2024
1 parent 34d2769 commit 6ac5703
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 141 deletions.
30 changes: 6 additions & 24 deletions packages/foundry/contracts/hooks/VeBALFeeDiscountHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,7 @@ contract VeBALFeeDiscountHook is BaseHooks {
_veBAL = veBAL;
}

/**
* @notice Hook executed when pool is registered
* @dev Return true if registration was successful
* @dev Return false to revert the registration of the pool
* @dev Vault address can be accessed with msg.sender
* @param factory Address of the pool factory
* @param pool Address of the pool
* @return success True if the hook allowed the registration, false otherwise
*/
// Determines if a pool is allowed to register using this hook
function onRegister(
address factory,
address pool,
Expand All @@ -49,41 +41,31 @@ contract VeBALFeeDiscountHook is BaseHooks {
return factory == _allowedFactory && IBasePoolFactory(factory).isPoolFromFactory(pool);
}

/**
* @notice Returns flags informing which hooks are implemented in the contract.
* @return hookFlags Flags indicating which hooks the contract supports
*/
// Return HookFlags struct that indicates which hooks this contract supports
function getHookFlags() public pure override returns (HookFlags memory hookFlags) {
// Support the `onComputeDynamicSwapFeePercentage` hook
hookFlags.shouldCallComputeDynamicSwapFee = true;
}

/**
* @notice Called before `onBeforeSwap` if the pool has dynamic fees.
* @param params Swap parameters (see IBasePool.PoolSwapParams for struct definition)
* @param staticSwapFeePercentage Value of the static swap fee, for reference
* @return success True if the pool wishes to proceed with settlement
* @return dynamicSwapFee Value of the swap fee
*/
// Alter the swap fee percentage
function onComputeDynamicSwapFeePercentage(
PoolSwapParams calldata params,
address, // pool
uint256 staticSwapFeePercentage
) public view override returns (bool success, uint256 dynamicSwapFee) {
) public view override returns (bool success, uint256 dynamicSwapFeePercentage) {
// If the router is not trusted, do not apply a fee discount
if (params.router != _trustedRouter) {
return (true, staticSwapFeePercentage);
}

// Find the user's address
// If the user owns veBAL, apply a 50% discount to the swap fee
address user = IRouterCommon(params.router).getSender();

// If the user owns veBAL, apply a 50% discount to the swap fee
if (IERC20(_veBAL).balanceOf(user) > 0) {
return (true, staticSwapFeePercentage / 2);
}

// Otherwise, do not apply the discount
// If the user holds zero veBAL, no discount
return (true, staticSwapFeePercentage);
}
}
2 changes: 0 additions & 2 deletions packages/foundry/script/01_DeployConstantSumPool.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ contract DeployConstantSumPool is PoolHelpers, ScaffoldHelpers {
uint256 deployerPrivateKey = getDeployerPrivateKey();
vm.startBroadcast(deployerPrivateKey);

console.log("msg.sender: %s", msg.sender);

// Deploy a factory
ConstantSumFactory factory = new ConstantSumFactory(vault, 365 days); // pauseWindowDuration
console.log("Constant Sum Factory deployed at: %s", address(factory));
Expand Down
1 change: 0 additions & 1 deletion packages/nextjs/app/pools/_components/PoolAttributes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const PoolAttributes = ({ pool }: { pool: Pool }) => {
{ attribute: "Vault Address", detail: <Address address={pool.vaultAddress} /> },
];

console.log("weightedPool", pool);
return (
<div className="w-full">
<div className="overflow-x-auto rounded-lg bg-base-200 p-5 shadow-lg">
Expand Down
91 changes: 31 additions & 60 deletions packages/nextjs/app/pools/_components/actions/TokenField.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction } from "react";
import { ChevronDownIcon } from "@heroicons/react/24/outline";
import { WalletIcon } from "@heroicons/react/24/outline";
import { type PoolTokens } from "~~/hooks/balancer/types";

interface TokenFieldProps {
Expand All @@ -17,12 +18,6 @@ interface TokenFieldProps {
setMaxAmount?: () => void;
}

/**
* Input field for token amounts
* (optional dropdown for swap token selection)
* (optional allowance and balance displays)
* (optional setMaxAmount button)
*/
export const TokenField: React.FC<TokenFieldProps> = ({
label,
value,
Expand All @@ -32,12 +27,12 @@ export const TokenField: React.FC<TokenFieldProps> = ({
tokenDropdownOpen,
setTokenDropdownOpen,
selectableTokens,
allowance,
// allowance,
balance,
isHighlighted,
setMaxAmount,
}) => {
const isTokenSwapField = !!(setTokenDropdownOpen && onTokenSelect && selectableTokens);
const isSwap = !!(setTokenDropdownOpen && onTokenSelect && selectableTokens);

return (
<div className="mb-5">
Expand All @@ -52,69 +47,45 @@ export const TokenField: React.FC<TokenFieldProps> = ({
value={value}
onChange={e => onAmountChange(e.target.value)}
placeholder="0.0"
className={`text-right text-2xl w-full input shadow-inner rounded-lg bg-base-300 p-10 ${
className={`text-right text-3xl w-full input shadow-inner rounded-lg bg-base-300 h-24 ${
isHighlighted ? "ring-1 ring-purple-500" : ""
}`}
/>
<div className="absolute top-0 left-0 flex gap-3 p-3">
{isTokenSwapField ? (
<div className="relative">
<div
onClick={() => setTokenDropdownOpen(!tokenDropdownOpen)}
tabIndex={0}
role="button"
className="bg-neutral hover:bg-base-100 rounded-lg w-28 flex items-center justify-center gap-2 font-bold h-[58px] p-2"
>
{tokenSymbol} <ChevronDownIcon className="w-4 h-4" />
</div>
{tokenDropdownOpen && (
<ul tabIndex={0} className="mt-2 dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
{selectableTokens.map(token => (
<div className="relative">
<button
onClick={() => setTokenDropdownOpen && setTokenDropdownOpen(!tokenDropdownOpen)}
tabIndex={0}
role="button"
disabled={!isSwap}
className={`${
isSwap && "hover:bg-base-100 "
} text-lg bg-neutral rounded-lg px-5 flex items-center justify-center gap-2 font-bold h-[55px] mb-0.5`}
>
{tokenSymbol} {isSwap && <ChevronDownIcon className="w-5 h-5" />}
</button>
{tokenDropdownOpen ? (
<ul tabIndex={0} className="mt-2 dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
{selectableTokens &&
onTokenSelect &&
selectableTokens.map(token => (
<li
key={token.symbol}
onClick={() => onTokenSelect(token.symbol)}
className="hover:bg-neutral-400 hover:bg-opacity-40 rounded-xl"
className="hover:bg-neutral-400 hover:bg-opacity-40 rounded-xl text-lg"
>
<a className="font-bold">{token.symbol}</a>
</li>
))}
</ul>
)}
</div>
) : (
<div>
<div className="min-w-[100px] bg-neutral rounded-lg flex items-center justify-center gap-2 font-bold h-[58px] px-5">
{tokenSymbol}
</div>
</div>
)}
{!tokenDropdownOpen && (
<div className="flex flex-col gap-1 justify-center text-sm">
<table className="">
<tbody className="">
{allowance && (
<tr>
<td className="align-top">Allowed :</td>
<td className="pl-1">{allowance}</td>
</tr>
)}
{balance && (
<tr>
<td className="align-top">Balance :</td>
<td className="pl-1">
{balance}{" "}
{setMaxAmount && (
<button className="text-violet-400" onClick={setMaxAmount}>
Max
</button>
)}
</td>
</tr>
)}
</tbody>
</table>
</div>
)}
</ul>
) : (
balance && (
<div onClick={setMaxAmount} className="flex items-center gap-1 hover:text-accent hover:cursor-pointer">
<WalletIcon className="h-4 w-4 mt-0.5" /> {balance}
</div>
)
)}
</div>
</div>
</div>
</div>
Expand Down
50 changes: 13 additions & 37 deletions packages/nextjs/contracts/deployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
31337: {
MockToken1: {
address: "0x83f953D2461C6352120E06f5f8EcCD3e4d66d042",
address: "0xA771fE4afEf7A16243AB045cc0F1aeb627428d54",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -365,7 +365,7 @@ const deployedContracts = {
},
},
MockToken2: {
address: "0x9d57eDCe10b7BdDA98997613c33ff7f3e34F4eAd",
address: "0xCeA42315FBfc3C23dfF6d158BcA5a370AcA4D7c0",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -723,7 +723,7 @@ const deployedContracts = {
},
},
MockVeBAL: {
address: "0x36F225dB9570eF972B3f2fACE74F472133606cc0",
address: "0x53e55cFD4141455862A46F98F9Dfe3Aa561EA797",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -1081,7 +1081,7 @@ const deployedContracts = {
},
},
ConstantSumFactory: {
address: "0x679F1F7a4F18975C1295BC411947E83d711E63a4",
address: "0x58c09BB978cfe368f638C74641dD0d7Fed7c3974",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -1465,7 +1465,7 @@ const deployedContracts = {
},
},
LotteryHook: {
address: "0x814E334C3CAcE7aB317B65F58F62aAD277637dB3",
address: "0xA2f3fE5972995b015392fC9499F22dDe9eB09ee7",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -2325,7 +2325,7 @@ const deployedContracts = {
},
},
ConstantProductFactory: {
address: "0x0576265d57700093a9Eb3Dc8777bAfE5C649913D",
address: "0x231485A6fd6b18387781D8173C73Ea616142B400",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -2709,7 +2709,7 @@ const deployedContracts = {
},
},
VeBALFeeDiscountHook: {
address: "0x538D4d1F18d6Ce7B30C683Dd3ab8f5b93b673B95",
address: "0x6496Ca5D0d8986A806478f2f976b48b20C692D55",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -3282,7 +3282,7 @@ const deployedContracts = {
internalType: "bool",
},
{
name: "dynamicSwapFee",
name: "dynamicSwapFeePercentage",
type: "uint256",
internalType: "uint256",
},
Expand Down Expand Up @@ -3368,22 +3368,10 @@ const deployedContracts = {
stateMutability: "view",
},
],
inheritedFunctions: {
getHookFlags: "vault/contracts/BaseHooks.sol",
onAfterAddLiquidity: "vault/contracts/BaseHooks.sol",
onAfterInitialize: "vault/contracts/BaseHooks.sol",
onAfterRemoveLiquidity: "vault/contracts/BaseHooks.sol",
onAfterSwap: "vault/contracts/BaseHooks.sol",
onBeforeAddLiquidity: "vault/contracts/BaseHooks.sol",
onBeforeInitialize: "vault/contracts/BaseHooks.sol",
onBeforeRemoveLiquidity: "vault/contracts/BaseHooks.sol",
onBeforeSwap: "vault/contracts/BaseHooks.sol",
onComputeDynamicSwapFeePercentage: "vault/contracts/BaseHooks.sol",
onRegister: "vault/contracts/BaseHooks.sol",
},
inheritedFunctions: {},
},
WeightedPoolFactory: {
address: "0x37eFddF706dcbD55ad4E8b5D4DDAcf970d4c2e93",
address: "0xEaEACf0637773DDC12d70D9D9F1FFBd024f0A984",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -3788,7 +3776,7 @@ const deployedContracts = {
},
},
ExitFeeHook: {
address: "0x0e8eBBd5590E4aD7fA19297eceaA238aa0361898",
address: "0x1716c987F768c18babbFCfc02A550a9bd1BC0647",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -7012,7 +7000,7 @@ const deployedContracts = {
internalType: "bool",
},
{
name: "dynamicSwapFee",
name: "dynamicSwapFeePercentage",
type: "uint256",
internalType: "uint256",
},
Expand Down Expand Up @@ -7098,19 +7086,7 @@ const deployedContracts = {
stateMutability: "view",
},
],
inheritedFunctions: {
getHookFlags: "vault/contracts/BaseHooks.sol",
onAfterAddLiquidity: "vault/contracts/BaseHooks.sol",
onAfterInitialize: "vault/contracts/BaseHooks.sol",
onAfterRemoveLiquidity: "vault/contracts/BaseHooks.sol",
onAfterSwap: "vault/contracts/BaseHooks.sol",
onBeforeAddLiquidity: "vault/contracts/BaseHooks.sol",
onBeforeInitialize: "vault/contracts/BaseHooks.sol",
onBeforeRemoveLiquidity: "vault/contracts/BaseHooks.sol",
onBeforeSwap: "vault/contracts/BaseHooks.sol",
onComputeDynamicSwapFeePercentage: "vault/contracts/BaseHooks.sol",
onRegister: "vault/contracts/BaseHooks.sol",
},
inheritedFunctions: {},
},
},
} as const;
Expand Down
Loading

0 comments on commit 6ac5703

Please sign in to comment.