-
Notifications
You must be signed in to change notification settings - Fork 465
Conversation
ba6f7d5
to
c375398
Compare
state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this)); | ||
|
||
// Grant the Uniswap router an allowance. | ||
LibERC20Token.approve( |
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.
There should be a LibERC20Token .approveIfBelow
so we keep it as high as possible and only write the state (expensive) if we have to.
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 also important for USDT and some others, which will fail after the first approve()
.
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.
okiedokie will switch
block.timestamp | ||
); | ||
|
||
state.boughtAmount = amounts[0]; |
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.
| amounts | uint[] memory | The input token amount and all subsequent output token amounts.|
https://uniswap.org/docs/v2/smart-contracts/router/#swapexacttokensfortokens
does this mean the first element is amountSold?
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.
Yeah seems like we want the second element 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.
Could also just do state.boughtAmount = router.swapExactTokensForTokens(...)[1]
.
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.
Oops my bad. Looks like we want the second element (last element if more than 2 tokens in the path).
state.fromTokenBalance = IERC20Token(state.fromTokenAddress).balanceOf(address(this)); | ||
|
||
// Grant the Uniswap router an allowance. | ||
LibERC20Token.approve( |
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 also important for USDT and some others, which will fail after the first approve()
.
block.timestamp | ||
); | ||
|
||
state.boughtAmount = amounts[0]; |
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.
Yeah seems like we want the second element here.
block.timestamp | ||
); | ||
|
||
state.boughtAmount = amounts[0]; |
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 also just do state.boughtAmount = router.swapExactTokensForTokens(...)[1]
.
IWallet, | ||
DeploymentConstants | ||
{ | ||
using LibAddressArray for address[]; |
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.
Think you don't need this.
address[] memory path = new address[](2); | ||
path[0] = state.fromTokenAddress; | ||
path[1] = toTokenAddress; |
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 thought there would be multihop support out of the gate? Should we just encode an address[] path
as the bridge data?
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.
Ya let's do that. I'll change it.
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.
Small nits, but otherwise great job on this!
👁️ 👁️
:nose:
:lips:
|
||
// Decode the bridge data to get the `fromTokenAddress`. | ||
// solhint-disable indent | ||
(state.path) = abi.decode(bridgeData, (address[])); |
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 you can just do state.path = ...
here?
IWallet, | ||
DeploymentConstants | ||
{ | ||
|
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.
No need for empty line here (this rule is confusing, I know).
require(state.path.length >= 2, "PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | ||
require(state.path[state.path.length - 1] == toTokenAddress, "LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_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.
require(state.path.length >= 2, "PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | |
require(state.path[state.path.length - 1] == toTokenAddress, "LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); | |
require(state.path.length >= 2, "UniswapV2Bridge/PATH_LENGTH_MUST_BE_AT_LEAST_TWO"); | |
require(state.path[state.path.length - 1] == toTokenAddress, "UniswapV2Bridge/LAST_ELEMENT_OF_PATH_MUST_MATCH_OUTPUT_TOKEN"); |
struct TransferState { | ||
address[] path; | ||
uint256 fromTokenBalance; | ||
uint256 boughtAmount; |
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.
No real point to this field since we can just access amounts[amounts.length-1]
.
function createTransferFromOpts(opts?: Partial<TransferFromOpts>): TransferFromOpts { | ||
const amount = getRandomInteger(1, TO_TOKEN_BASE.times(100)); | ||
return { | ||
tokenAddressesPath: Array(2).fill(constants.NULL_ADDRESS), |
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.
Where has this pattern been all my life.
Description
Implement UniswapV2Bridge contract. Allows us to swap tokens through the UniswapV2 Router.
Testing instructions
Please review unit tests and comment if you think any cases should be added.
Types of changes
Checklist:
[WIP]
if necessary.