Skip to content

Commit 444a61e

Browse files
committed
Automatically fix balances within tolerance, remove unused Uniswap component
1 parent d7c7f91 commit 444a61e

File tree

7 files changed

+67
-113
lines changed

7 files changed

+67
-113
lines changed

web/src/App.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<div class="container">
55
<Menubar :model="items">
66
<template #start>
7-
<router-link to="/" class="logo"><img src="@/assets/logo.png" class="img-fluid"> TokenBlend</router-link>
7+
<router-link to="/" class="logo"
8+
><img src="@/assets/logo.png" class="img-fluid" /> TokenBlend</router-link
9+
>
810
</template>
911
</Menubar>
1012
</div>
@@ -65,4 +67,4 @@ export default defineComponent({
6567
width: 2rem;
6668
height: 2rem;
6769
}
68-
</style>
70+
</style>

web/src/components/OrderPlanDialog.vue

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@
9696

9797
<script lang="ts">
9898
import { PlannedOrder, OrderType } from '@/orderplan/orderplan';
99-
import { bigNumberToFixed, compareBignumber, formatMaxDigits, numberMixin } from '@/util/numbers';
99+
import {
100+
bigNumberToFixed,
101+
compareBignumber,
102+
fixedToBigNumber,
103+
formatMaxDigits,
104+
numberMixin,
105+
toleranceMin,
106+
} from '@/util/numbers';
107+
import { getTokenBalance } from '@/util/tokens';
100108
import { idleService } from '@/web3/idleService';
101109
import { ParaSwapPredictedOutput, paraswapService, PredictedOutput } from '@/web3/paraswapService';
102110
import { TransactionResult, uniswapService } from '@/web3/uniswapService';
@@ -142,6 +150,10 @@ export default defineComponent({
142150
},
143151
methods: {
144152
async calculateBest(order: OrderWithResult) {
153+
const address = web3Service.status().address;
154+
if (!address) {
155+
throw new Error('web3 not initialized yet');
156+
}
145157
const uniswapOption: Option = reactive({
146158
platform: 'Uniswap',
147159
inProgress: true,
@@ -151,13 +163,14 @@ export default defineComponent({
151163
inProgress: true,
152164
});
153165
order.options = [uniswapOption, paraswapOption];
166+
await this.prepareOrder(order, address);
154167
const uniswapOutput = uniswapService.getPredictedOutput(order).then((output) => {
155-
console.log("output uniswap: " , output);
168+
console.log('output uniswap: ', output);
156169
uniswapOption.inProgress = false;
157170
uniswapOption.plan = output;
158171
});
159172
const paraswapOutput = paraswapService.getPredictedOutput(order).then((output) => {
160-
console.log("output paraswap: " , output);
173+
console.log('output paraswap: ', output);
161174
paraswapOption.inProgress = false;
162175
paraswapOption.plan = output;
163176
});
@@ -195,6 +208,7 @@ export default defineComponent({
195208
executeFunction = (order) =>
196209
idleService.redeemToken(order.fromToken, address, order.sendAmount);
197210
} else {
211+
await this.prepareOrder(order, address);
198212
if (platform === undefined) {
199213
// work on a copy so we keep the UI clean
200214
const copy = { ...order };
@@ -239,7 +253,7 @@ export default defineComponent({
239253
return '---';
240254
}
241255
const fixed = bigNumberToFixed(result, order.toToken.decimals);
242-
return order.toToken.symbol + " " + formatMaxDigits(fixed.toUnsafeFloat());
256+
return order.toToken.symbol + ' ' + formatMaxDigits(fixed.toUnsafeFloat());
243257
},
244258
isSwap(order: PlannedOrder): boolean {
245259
return order.ordertype == OrderType.SWAP;
@@ -267,6 +281,13 @@ export default defineComponent({
267281
return name;
268282
}
269283
},
284+
async prepareOrder(order: PlannedOrder, address: string) {
285+
// Make sure that the amount wanted is not higher than our balance
286+
const balance = await getTokenBalance(order.fromToken.id, address);
287+
const amountBn = fixedToBigNumber(order.sendAmount, order.fromToken.decimals);
288+
const newAmount = toleranceMin(amountBn, balance);
289+
order.sendAmount = bigNumberToFixed(newAmount, order.fromToken.decimals);
290+
},
270291
},
271292
mixins: [numberMixin],
272293
});

web/src/router/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import Home from '../views/Home.vue';
33
import EnzymeAccount from '../views/EnzymeAccount.vue';
44
import WalletAccount from '../views/WalletAccount.vue';
55

6-
import Uniswap from '../views/Uniswap.vue';
7-
86
const routes: Array<RouteRecordRaw> = [
97
{
108
path: '/',
@@ -22,11 +20,6 @@ const routes: Array<RouteRecordRaw> = [
2220
name: 'WalletAccount',
2321
component: WalletAccount,
2422
},
25-
{
26-
path: '/uniswap',
27-
name: 'Uniswap',
28-
component: Uniswap,
29-
},
3023
];
3124

3225
const router = createRouter({

web/src/util/numbers.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,36 @@ function reduceDecimalString(value: string, decimals: number): string {
1414
return parts[0] + '.' + parts[1].substr(0, decimals);
1515
}
1616

17+
/**
18+
* Make sure amount is lower than balance, as long as it's maximum tolerance x higher.
19+
* We frequently try to e.g. sell all tokens and this amount may be dependent on an earlier trade
20+
* that may have executed at a less favorable rate than expected.
21+
* This will then cause trades to fail because the requested amount is a tiny bit too high, this fixes that.
22+
*
23+
* The tolerance is there to not just reduce some crazy high amount back to balance, but that we still
24+
* get an error then, because probably there's some bug or other problem happening.
25+
*/
26+
export function toleranceMin(amount: BigNumber, balance: BigNumber, tolerance = 0.1): BigNumber {
27+
if (amount.lte(balance)) {
28+
return amount;
29+
}
30+
// Check if amount is within tolerance
31+
const toleranceAmount = fixedToBigNumber(
32+
bigNumberToFixed(balance, 18).mulUnsafe(fixedNum(1 + tolerance)),
33+
18
34+
);
35+
if (amount.gt(toleranceAmount)) {
36+
throw new Error(`Amount ${amount.toString()} much bigger than balance ${balance.toString()}`);
37+
}
38+
console.log(
39+
`Downwards adjusting number from ${bigNumberToFixed(amount, 18)} to ${bigNumberToFixed(
40+
balance,
41+
18
42+
)}`
43+
);
44+
return balance;
45+
}
46+
1747
export function compareFixed(a: FixedNumber, b: FixedNumber): number {
1848
const bn1 = fixedToBigNumber(a, 18);
1949
const bn2 = fixedToBigNumber(b, 18);

web/src/views/Home.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<div class="home">
33
<div class="hero position-relative text-center p-4">
4-
<h1 class="display-1"><img src="@/assets/logo.png"> TokenBlend</h1>
4+
<h1 class="display-1"><img src="@/assets/logo.png" /> TokenBlend</h1>
55
<h2 class="h2">Asset allocation for your Enzyme funds and Ethereum wallet</h2>
66
</div>
77
</div>

web/src/views/Uniswap.vue

Lines changed: 0 additions & 86 deletions
This file was deleted.

web/src/web3/idleService.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { bigNumberToFixed, fixedToBigNumber, formatMaxDigits } from '@/util/numbers';
1+
import { bigNumberToFixed, fixedToBigNumber, formatMaxDigits, toleranceMin } from '@/util/numbers';
22
import { StakedToken } from '@/util/stakedTokens';
33
import { getTokenAllowance, getTokenBalance, tokenApprove, TokenData } from '@/util/tokens';
44
import { BigNumber, Contract, FixedNumber, utils } from 'ethers';
@@ -101,8 +101,11 @@ class IdleService {
101101
const ok = await tokenApprove(token.id, contractAddress, unlimitedAllowance);
102102
console.log('token approve: ' + ok);
103103
}
104-
console.log(amountBn, amountBn.toString());
105-
const result = await contract.mintIdleToken(amountBn, true, accountAddress);
104+
105+
const balance = await getTokenBalance(token.id, accountAddress);
106+
const finalAmount = toleranceMin(amountBn, balance);
107+
108+
const result = await contract.mintIdleToken(finalAmount, true, accountAddress);
106109
console.log(result);
107110
const receipt = await result.wait();
108111
console.log(receipt);
@@ -128,16 +131,7 @@ class IdleService {
128131
let redeemAmount = fixedToBigNumber(amount.divUnsafe(bigNumberToFixed(priceWithFee, 18)), 18);
129132

130133
const balance: BigNumber = await contract.balanceOf(accountAddress);
131-
if (redeemAmount.gt(balance)) {
132-
// If there's more than 10% difference, throw, otherwise just adjust to maximum
133-
if (redeemAmount.sub(balance).gt(redeemAmount.div(10))) {
134-
throw new Error(
135-
`Tried to redeem ${redeemAmount.toString()} (from ${amount.toString()} original), but balance is ${balance.toString()}`
136-
);
137-
}
138-
console.log('Trying to redeem more than balance, adjusting to redeem max balance');
139-
redeemAmount = balance;
140-
}
134+
redeemAmount = toleranceMin(redeemAmount, balance);
141135

142136
const result = await contract.redeemIdleToken(redeemAmount);
143137
console.log(result);

0 commit comments

Comments
 (0)