use safe erc20 & new logGas
This commit is contained in:
@@ -15,12 +15,10 @@ import {IDODO} from "./intf/IDODO.sol";
|
|||||||
import {IERC20} from "./intf/IERC20.sol";
|
import {IERC20} from "./intf/IERC20.sol";
|
||||||
import {IWETH} from "./intf/IWETH.sol";
|
import {IWETH} from "./intf/IWETH.sol";
|
||||||
|
|
||||||
|
|
||||||
interface IDODOZoo {
|
interface IDODOZoo {
|
||||||
function getDODO(address baseToken, address quoteToken) external view returns (address);
|
function getDODO(address baseToken, address quoteToken) external view returns (address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title DODO Eth Proxy
|
* @title DODO Eth Proxy
|
||||||
* @author DODO Breeder
|
* @author DODO Breeder
|
||||||
@@ -112,7 +110,7 @@ contract DODOEthProxy is ReentrancyGuard {
|
|||||||
require(DODO != address(0), "DODO_NOT_EXIST");
|
require(DODO != address(0), "DODO_NOT_EXIST");
|
||||||
payTokenAmount = IDODO(DODO).queryBuyBaseToken(ethAmount);
|
payTokenAmount = IDODO(DODO).queryBuyBaseToken(ethAmount);
|
||||||
_transferIn(quoteTokenAddress, msg.sender, payTokenAmount);
|
_transferIn(quoteTokenAddress, msg.sender, payTokenAmount);
|
||||||
IERC20(quoteTokenAddress).approve(DODO, payTokenAmount);
|
IERC20(quoteTokenAddress).safeApprove(DODO, payTokenAmount);
|
||||||
IDODO(DODO).buyBaseToken(ethAmount, maxPayTokenAmount, "");
|
IDODO(DODO).buyBaseToken(ethAmount, maxPayTokenAmount, "");
|
||||||
IWETH(_WETH_).withdraw(ethAmount);
|
IWETH(_WETH_).withdraw(ethAmount);
|
||||||
msg.sender.transfer(ethAmount);
|
msg.sender.transfer(ethAmount);
|
||||||
@@ -127,7 +125,7 @@ contract DODOEthProxy is ReentrancyGuard {
|
|||||||
) external preventReentrant returns (uint256 receiveEthAmount) {
|
) external preventReentrant returns (uint256 receiveEthAmount) {
|
||||||
address DODO = IDODOZoo(_DODO_ZOO_).getDODO(baseTokenAddress, _WETH_);
|
address DODO = IDODOZoo(_DODO_ZOO_).getDODO(baseTokenAddress, _WETH_);
|
||||||
require(DODO != address(0), "DODO_NOT_EXIST");
|
require(DODO != address(0), "DODO_NOT_EXIST");
|
||||||
IERC20(baseTokenAddress).approve(DODO, tokenAmount);
|
IERC20(baseTokenAddress).safeApprove(DODO, tokenAmount);
|
||||||
_transferIn(baseTokenAddress, msg.sender, tokenAmount);
|
_transferIn(baseTokenAddress, msg.sender, tokenAmount);
|
||||||
receiveEthAmount = IDODO(DODO).sellBaseToken(tokenAmount, minReceiveEthAmount, "");
|
receiveEthAmount = IDODO(DODO).sellBaseToken(tokenAmount, minReceiveEthAmount, "");
|
||||||
IWETH(_WETH_).withdraw(receiveEthAmount);
|
IWETH(_WETH_).withdraw(receiveEthAmount);
|
||||||
|
|||||||
@@ -45,6 +45,22 @@ library SafeERC20 {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function safeApprove(
|
||||||
|
IERC20 token,
|
||||||
|
address spender,
|
||||||
|
uint256 value
|
||||||
|
) internal {
|
||||||
|
// safeApprove should only be called when setting an initial allowance,
|
||||||
|
// or when resetting it to zero. To increase and decrease it, use
|
||||||
|
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
|
||||||
|
// solhint-disable-next-line max-line-length
|
||||||
|
require(
|
||||||
|
(value == 0) || (token.allowance(address(this), spender) == 0),
|
||||||
|
"SafeERC20: approve from non-zero to non-zero allowance"
|
||||||
|
);
|
||||||
|
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
|
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
|
||||||
* on the return value: the return value is optional (but if data is returned, it must not be false).
|
* on the return value: the return value is optional (but if data is returned, it must not be false).
|
||||||
|
|||||||
@@ -101,14 +101,14 @@ describe("DODO ETH PROXY", () => {
|
|||||||
describe("buy&sell eth directly", () => {
|
describe("buy&sell eth directly", () => {
|
||||||
it("buy", async () => {
|
it("buy", async () => {
|
||||||
const buyAmount = "1";
|
const buyAmount = "1";
|
||||||
logGas(
|
await logGas(
|
||||||
await DODOEthProxy.methods
|
DODOEthProxy.methods
|
||||||
.buyEthWithToken(
|
.buyEthWithToken(
|
||||||
ctx.QUOTE.options.address,
|
ctx.QUOTE.options.address,
|
||||||
decimalStr(buyAmount),
|
decimalStr(buyAmount),
|
||||||
decimalStr("200")
|
decimalStr("200")
|
||||||
)
|
),
|
||||||
.send(ctx.sendParam(trader)),
|
ctx.sendParam(trader),
|
||||||
"buy ETH with token directly"
|
"buy ETH with token directly"
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
@@ -122,14 +122,14 @@ describe("DODO ETH PROXY", () => {
|
|||||||
});
|
});
|
||||||
it("sell", async () => {
|
it("sell", async () => {
|
||||||
const sellAmount = "1";
|
const sellAmount = "1";
|
||||||
logGas(
|
await logGas(
|
||||||
await DODOEthProxy.methods
|
DODOEthProxy.methods
|
||||||
.sellEthToToken(
|
.sellEthToToken(
|
||||||
ctx.QUOTE.options.address,
|
ctx.QUOTE.options.address,
|
||||||
decimalStr(sellAmount),
|
decimalStr(sellAmount),
|
||||||
decimalStr("50")
|
decimalStr("50")
|
||||||
)
|
),
|
||||||
.send(ctx.sendParam(trader, sellAmount)),
|
ctx.sendParam(trader, sellAmount),
|
||||||
"sell ETH to token directly"
|
"sell ETH to token directly"
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
|||||||
@@ -103,14 +103,12 @@ describe("DODO ETH PROXY", () => {
|
|||||||
const maxPayEthAmount = "2.1";
|
const maxPayEthAmount = "2.1";
|
||||||
const ethInPoolBefore = decimalStr("10");
|
const ethInPoolBefore = decimalStr("10");
|
||||||
const traderEthBalanceBefore = await ctx.Web3.eth.getBalance(trader);
|
const traderEthBalanceBefore = await ctx.Web3.eth.getBalance(trader);
|
||||||
const txReceipt: TransactionReceipt = await DODOEthProxy.methods
|
const txReceipt: TransactionReceipt = await logGas(DODOEthProxy.methods
|
||||||
.buyTokenWithEth(
|
.buyTokenWithEth(
|
||||||
ctx.BASE.options.address,
|
ctx.BASE.options.address,
|
||||||
decimalStr("200"),
|
decimalStr("200"),
|
||||||
decimalStr(maxPayEthAmount)
|
decimalStr(maxPayEthAmount)
|
||||||
)
|
), ctx.sendParam(trader, maxPayEthAmount), "buy token with ETH directly");
|
||||||
.send(ctx.sendParam(trader, maxPayEthAmount));
|
|
||||||
logGas(txReceipt, "buy token with ETH directly");
|
|
||||||
const ethInPoolAfter = "12056338203652739553";
|
const ethInPoolAfter = "12056338203652739553";
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
|
await ctx.DODO.methods._QUOTE_BALANCE_().call(),
|
||||||
@@ -134,14 +132,14 @@ describe("DODO ETH PROXY", () => {
|
|||||||
});
|
});
|
||||||
it("sell", async () => {
|
it("sell", async () => {
|
||||||
const minReceiveEthAmount = "0.45";
|
const minReceiveEthAmount = "0.45";
|
||||||
logGas(
|
await logGas(
|
||||||
await DODOEthProxy.methods
|
DODOEthProxy.methods
|
||||||
.sellTokenToEth(
|
.sellTokenToEth(
|
||||||
ctx.BASE.options.address,
|
ctx.BASE.options.address,
|
||||||
decimalStr("50"),
|
decimalStr("50"),
|
||||||
decimalStr(minReceiveEthAmount)
|
decimalStr(minReceiveEthAmount)
|
||||||
)
|
),
|
||||||
.send(ctx.sendParam(trader)),
|
ctx.sendParam(trader),
|
||||||
"sell token to ETH directly"
|
"sell token to ETH directly"
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
|||||||
@@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TransactionReceipt } from "web3-core"
|
|
||||||
|
|
||||||
export const blueText = x => `\x1b[36m${x}\x1b[0m`;
|
export const blueText = x => `\x1b[36m${x}\x1b[0m`;
|
||||||
export const yellowText = x => `\x1b[33m${x}\x1b[0m`;
|
export const yellowText = x => `\x1b[33m${x}\x1b[0m`;
|
||||||
export const greenText = x => `\x1b[32m${x}\x1b[0m`;
|
export const greenText = x => `\x1b[32m${x}\x1b[0m`;
|
||||||
export const redText = x => `\x1b[31m${x}\x1b[0m`;
|
export const redText = x => `\x1b[31m${x}\x1b[0m`;
|
||||||
export const numberWithCommas = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
export const numberWithCommas = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
|
||||||
export function logGas(receipt: TransactionReceipt, desc: string) {
|
export async function logGas(funcCall: any, params: any, desc: string) {
|
||||||
|
const estimatedGas = await funcCall.estimateGas(params)
|
||||||
|
const receipt = await funcCall.send(params)
|
||||||
const gasUsed = receipt.gasUsed;
|
const gasUsed = receipt.gasUsed;
|
||||||
let colorFn;
|
let colorFn;
|
||||||
|
|
||||||
@@ -25,5 +25,6 @@ export function logGas(receipt: TransactionReceipt, desc: string) {
|
|||||||
colorFn = redText;
|
colorFn = redText;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(("Gas used:").padEnd(60, '.'), blueText(desc) + " ", colorFn(numberWithCommas(gasUsed).padStart(5)));
|
console.log(("Gas estimated:" + numberWithCommas(estimatedGas)).padEnd(60, '.'), blueText(desc) + " ", colorFn(numberWithCommas(gasUsed).padStart(5)));
|
||||||
|
return receipt
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user