-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow swaps to be done on behalf of user via signed messages #8
- Loading branch information
1 parent
3fbfdd7
commit 21f7c32
Showing
9 changed files
with
153 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
pragma solidity ^0.8.0; | ||
|
||
import "./interfaces/IDCAManager.sol"; | ||
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol'; | ||
|
||
contract DCAManager is IDCAManager { | ||
|
||
IUniswapV2Router02 public uniswapRouter; | ||
|
||
constructor(address _uniswapV2Router) public { | ||
uniswapRouter = IUniswapV2Router02(_uniswapV2Router); | ||
} | ||
|
||
/* | ||
* See IDCAManager.sol | ||
*/ | ||
function swapOnUsersBehalf( | ||
address baseToken, | ||
uint amountBaseToken, | ||
address destinationToken, | ||
uint fromTime, | ||
uint toTime, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s | ||
) public override returns (bool) { | ||
require(block.timestamp >= fromTime && block.timestamp <= toTime, "failed to meet the time requirement"); | ||
// TODO have to be careful with this, if signed by a user via metamask it will add the ethereum message prefix | ||
bytes memory message = abi.encodePacked( | ||
baseToken, | ||
amountBaseToken, | ||
destinationToken, | ||
fromTime, | ||
toTime | ||
); | ||
bytes32 messageHash = keccak256(message); | ||
address user = ecrecover(messageHash, v, r, s); | ||
address[] memory path = new address[](2); | ||
path[0] = baseToken; | ||
path[1] = destinationToken; | ||
|
||
uniswapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens( | ||
amountBaseToken, | ||
0, // TODO set min amount of WETH using some kind of oracle | ||
path, | ||
user, | ||
toTime | ||
); | ||
return true; | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
pragma solidity ^0.8.0; | ||
|
||
interface IDCAManager { | ||
|
||
/* | ||
* @dev allow a relayer to trigger a trade on behalf of a user with their signed permission, | ||
* requires that the user approve this contract to move the base token | ||
* @param baseToken - the token to trade from | ||
* @param amountBaseToken - the amount of the base token to trade into the destination token | ||
* @param destinationToken - the address of the token that the user wants to swap their base token into | ||
* @param fromTime - the desired time for this swap to occur | ||
* @param toTime - this swap should happen no later than this | ||
* @param v - signature param | ||
* @param r - signature param | ||
* @param s - signature param | ||
* @returns true if successful | ||
*/ | ||
function swapOnUsersBehalf( | ||
address baseToken, | ||
uint amountBaseToken, | ||
address destinationToken, | ||
uint fromTime, | ||
uint toTime, | ||
uint8 v, | ||
bytes32 r, | ||
bytes32 s | ||
) external returns (bool); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,18 @@ | ||
{ | ||
"name": "drip-finance", | ||
"scripts": { | ||
"test": "npx hardhat test", | ||
"compile": "npx hardhat compile" | ||
}, | ||
"devDependencies": { | ||
"@nomiclabs/hardhat-ethers": "^2.0.2", | ||
"@nomiclabs/hardhat-waffle": "^2.0.1", | ||
"chai": "^4.3.4", | ||
"ethereum-waffle": "^3.3.0", | ||
"ethers": "^5.1.4", | ||
"hardhat": "^2.2.1" | ||
}, | ||
"dependencies": { | ||
"@uniswap/v2-periphery": "^1.1.0-beta.0" | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
const { expect } = require("chai"); | ||
|
||
//TODO complete | ||
describe("DCAManager functions", function() { | ||
|
||
before(async function() { | ||
const [user, relayer] = await ethers.getSigners(); | ||
this.user = user; | ||
this.relayer = relayer; | ||
const erc20 = await ethers.getContractFactory("ERC20"); | ||
const DCAManager = await ethers.getContractFactory("DCAManager"); | ||
//TODO get or deploy uniswap | ||
this.baseToken = await erc20.deploy("BASE", 18); | ||
this.destinationToken = await erc20.deploy("DEST", 18); | ||
this.DCAManager = await DCAManager.deploy("0x0000000000000000000000000000000000000000"); | ||
const defaultSwapOrder = { | ||
baseToken: this.baseToken.address, | ||
amountBaseToken: 100000000000, | ||
destinationToken: this.destinationToken.address, | ||
fromTime: 0, | ||
toTime: 100000000000000000000 | ||
}; | ||
this.order = defaultSwapOrder; | ||
//TODO make sure to pad | ||
const msg = `${defaultSwapOrder.baseToken}${defaultSwapOrder.amountBaseToken}${defaultSwapOrder.destinationToken}${defaultSwapOrder.fromTime}${defaultSwapOrder.toTime}` | ||
const flatSignature = await user.signMessage(msg); | ||
this.sig = ethers.utils.splitSignature(flatSignature); | ||
}); | ||
|
||
it("Should fail to swap due to lack of approval from user", async function() { | ||
expect(await this.DCAManager.swapOnUsersBehalf(...this.order, ...this.sig)).reverted; | ||
}); | ||
|
||
it("Should be able to swap on behalf of the user", async function() { | ||
const token = this.baseToken.connect(this.user); | ||
token.approve(this.DCAManager.address, "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") | ||
const DCAManager = this.DCAManager.connect(this.relayer); | ||
expect(await DCAManager.swapOnUsersBehalf(...this.order, ...this.sig)).to.equal(true, "swap executed"); | ||
}); | ||
}); |
This file was deleted.
Oops, something went wrong.