-
Notifications
You must be signed in to change notification settings - Fork 8
uniswapv3 amm adapter #10
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
Conversation
…r' into feature/uniswapv3-amm-adapter
feature interface was utilizing OZ's IERC20 in interface definition. This is unnecessarily type safe as the IERC20 functions aren't used.
Later compilers require valid spx identifiers.
constructor - public is ignored and has no meaning in that context. getProvideLiquiditySingleAssetCalldata, getRemoveLiquiditySingleAssetCalldata - restricted to pure.
Additionally, clarifies component matching pool test.
45c3327
to
3a0acb8
Compare
Note about checks:
|
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.
Mostly looking good. Only some nit-picking regarding the contracts (mostly documentation) as well as some suggestions on how to get the CI green.
@@ -0,0 +1,277 @@ | |||
/* | |||
Copyright 2022 Set Labs Inc. |
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.
Should be 2023 and (maybe) Index Coop. No ?
@@ -0,0 +1,83 @@ | |||
/* | |||
Copyright 2022 Set Labs Inc. |
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.
Wrong date and Copy Right holder. (Should be 2023 IndexCoop no ? )
|
||
/** | ||
* @title UniswapV3AmmAdapter | ||
* @author Zishan Sami |
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.
Without diminishing Zishans contribution I'd suggest changing this to "Index Coop" as we usually do for all contracts I think.
address setToken = _setToken; | ||
address[] memory components = _components; | ||
uint256[] memory maxTokensIn = _maxTokensIn; | ||
uint256 minLiquidity = _minLiquidity; |
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.
Why are we doing these reassignments ? Seems like a waste of gas no ? (For the arrays I suggest just changing the type to "memory" in the call signature if those arrays need to be edited. If they are read only then calldata is cheaper anyway.
address[] memory components = _components; | ||
uint256[] memory minTokensOut = _minTokensOut; | ||
uint256 liquidity = _liquidity; | ||
IArrakisVaultV1 arrakisVaultPool = IArrakisVaultV1(_pool); |
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.
Same here. Those reassignments seem unnecessary to me
method: "hardhat_reset", | ||
params: [ | ||
{ | ||
forking: { |
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 think this hardhat reset is causing the (seemingly unrelated) test failures in the other tests, since this change will persist and therefore lead to the other tests running against a different block.
We have two options here:
- Resetting to the state after running these tests to the previously pinned block number.
- Adjusting the other tests to work on this block number as well and then updating it for all tests in the hardhat config. I can support here if needed.
I'm a bit conflicted on which is better, but I think long term it might be nice to have different tests running against different block numbers so that we don't have to continously update some of the tests which assume specific market conditions / product states.
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.
Yet another option to update the blocknumber in hardhat-config and then do this "hardhat_reset" to the old blocknumber for all the test suites that are failing on the new block. I think this is probably the best solution as it should be the individual test suite's "responsibility" to ensure it is running agains the right block if it is sensitive to changes in market conditions / product composition etc.
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.
Yet another option to update the blocknumber in hardhat-config and then do this "hardhat_reset" to the old blocknumber for all the test suites that are failing on the new block. I think this is probably the best solution as it should be the individual test suite's "responsibility" to ensure it is running agains the right block if it is sensitive to changes in market conditions / product composition etc.
hmm I thought that addSnapshotBeforeRestoreAfterEach
would handle setting up a "resetting" to the snapshot after, but maybe its doing the snapshot after the fork which messes things up moving forward. I'll double check my understanding around this flow and likely try to implement this solution.
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 think the "before" function is executed before "beforeEach" so the snapshots are probably taken after the fork change and therefore the changed forked block will persist.
I remember having faced similar issues elsewhere though, it could be that the "snapshot" / "restore" rpc calls just don't play well wit the "reset".
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.
This is a great hint towards a solution. I think I can rework the before hook such that from a general level, the network is reset to the fork block for every test as expected.
try IArrakisVaultV1(_pool).token1() returns (address _token1) { | ||
token1 = _token1; | ||
} catch { | ||
return false; |
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 don't quite understand why we can't have this line covered, especially since line 234 seems to be covered.
Am I missing anything here ?
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.
Its not that we couldn't, but having a condition where the token0 external call succeeds and the token1 call fails would have to be done with a mock contract that exhibits this behavior.
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.
Ah I see. That explains why we can cover the first call easily but not the second one.
I still think adding this little mock contract might be worth it if it helps us to just keep it at a nice 100% coverage.
Also might be worth looking into other mock options such as smock ( or whatever the cool kids are using nowadays)
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 was scared of adding dependencies without upgrading existing dev deps, but I've heard of smock and would love to try it. If I run into an issue with configuring smock
, I'll just do a small mock contract to get this to 100% which I agree is nice and why I added a constructor test :)
|
||
/** | ||
* Return calldata for the add liquidity call for a single asset | ||
*/ |
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.
Please make sure all external methods have full docstring documentation including all parameters.
import "../../../interfaces/external/IArrakisVaultV1.sol"; | ||
|
||
/** | ||
* @title UniswapV3AmmAdapter |
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 title should probably be the same as the contract name.
|
||
target = router; | ||
value = 0; | ||
data = abi.encodeWithSignature( |
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 think we could do something like:
abi.encodeWithSelector(IArrakis.removeLiquidity.selector ...
here no ?
Advantages:
- No need of signature string constant
- Less error prone
- Maybe more efficient if the selector is precomputed at compile time
also skipping typechecking on libraries
side steps stack too deep error in some cases.
fixes issue with coverage stack too deep.
Continues on #8
Additionally: