-
Notifications
You must be signed in to change notification settings - Fork 68
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
feat(camelot-v3): Camelot V3 DEX integration. #20
base: main
Are you sure you want to change the base?
Conversation
Supported functionalities: - swap tokens - add liquidity - manage liquidity (increase, decrease, remove)
projects/camelot-v3/tools.ts
Outdated
{ | ||
name: 'exactInputSingle', | ||
description: 'Swap exact amount of X tokens A for token B receiving at least Y tokens B and optionally send them to another recipient', | ||
required: ['chainName', 'account', 'tokenIn', 'tokenOut', 'amountIn'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
export async function collect( | ||
{ chainName, account, tokenA, tokenB, tokenId, collectPercentage, amountAMax, amountBMax, recipient }: Props, | ||
{ sendTransactions, notify, getProvider }: FunctionOptions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add validation for tokenId. If it will be 3.52, then you will receive error at 47 line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
collectPercentage same 111 line
const result = await sendTransactions({ chainId, account, transactions }); | ||
const collectFees = result.data[result.data.length - 1]; | ||
|
||
return toResult(result.isMultisig ? collectFees.message : `Successfully collected fees on Camelot V3. ${collectFees.message}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider read events and display info from there to user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clarify what you mean in more detail? The idea is that after a user performs an action, they receive a more meaningful message. For example:
- A message confirming that the transaction is being processed.
- A message returning the transaction hash (SHOULD this be included?).
- A message with the action results—for example, how many fees were collected in this case (SHOULD this be included?).
Adding (2) is straightforward, but (3) could be more challenging since it requires waiting for the transaction to be mined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export async function amountToWei(provider: PublicClient, token: Address, amount: string | undefined): Promise<bigint> { | ||
if (!amount) return 0n; | ||
|
||
const decimals = await getDecimals(provider, token); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if(!name || !symbol || !decimals) throw new Error(Invalid ERC20 token contract at address ${address}. Failed to fetch token details (name: ${name}, symbol: ${symbol}, decimals: ${decimals})
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is already handled in the getDecimals()
function, which throws this error (*I’ve adjusted the error message). Since amountToWei
and weiToAmount
rely on getDecimals()
, they automatically return the rejected Promise when the error is thrown, as they don’t catch it internally.
export async function getDecimals(provider: PublicClient, token: Address): Promise<number> {
// Try-catch to detect invalid token address
try {
return provider.readContract({
address: token,
abi: erc20Abi,
functionName: 'decimals',
args: [],
});
} catch (error) {
throw new Error(`Invalid ERC20 token contract at address ${token}. Failed to fetch token details`);
}
}
const [simulatedAmount0, simulatedAmount1] = await simulateDecreaseLiquidityAmounts(chainId, provider, positionId, liquidityToRemove); | ||
|
||
// Set 0.2% slippage tolerance | ||
if (amount0MinWei == 0n) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if user need 0.5% slippage?
projects/camelot-v3/tools.ts
Outdated
}, | ||
{ | ||
name: 'exactOutputSingle', | ||
description: 'Swap token A for exact amount of X tokens B while spending at most Y tokens A and optionally send them to another recipient', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use tokenA tokenB then this arguments must be in function. I don't get it what for you use this examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like in mint function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exactOutputSingle
function allows you to buy EXACTLY 0.1 ETH using an arbitrary amount of USDC. In contrast, exactInputSingle
lets you spend EXACTLY 1000 USDC to purchase an arbitrary amount of ETH.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
exactOutputSingle
function allows you to buy EXACTLY 0.1 ETH using an arbitrary amount of USDC. In contrast,exactInputSingle
lets you spend EXACTLY 1000 USDC to purchase an arbitrary amount of ETH.
how it corresponding to my question?
} | ||
|
||
// TODO: How can we detect if user has input wrong lowerPrice? We can inverse it if necessary (i.e. tokenA != token0) | ||
// TODO: How can we detect if user has input wrong upperPrice? We can inverse it if necessary (i.e. tokenA != token0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. This function not ready. You must handle case when price inverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been thinking about absolute price inputs for a while, and I believe it might make sense to remove them. They can be too ambiguous for both the end user and the code to handle properly.
For example, if the current price of Ethereum is 2800 USD/ETH, the inverse price would be around 0.0003571 ETH/USD. If a user mistakenly defines a liquidity range as 0.0003 USD/ETH to 0.0004 USD/ETH (note the incorrect units), how would we know that the input was an error? We could introduce a threshold (e.g., if the price is more than 50% away from the current one, trigger an error), but that would still leave room for mistakes.
To avoid this, it might be safer to just use relative pricing, where the user sets the price as a percentage of the current price.
I’d love to hear your thoughts on this.
} | ||
|
||
function priceToTick( | ||
price: string | undefined, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is any problems with UniswapV3 SDK usage? priceToTick you can use from SDK
@OoXooOx I’ve addressed the highlighted comments. There are still a few outstanding ones, and I’d love to hear your feedback on them. Thanks! |
Supported functionalities:
Files Changed