EAST Update 1.2 is Here: Learn How to Liquidate Vaults

EAST.Finance
EAST.Finance
Published in
5 min readApr 8, 2022

--

EAST Update Version 1.2: How to Liquidate Vaults

We’re posting this beforehand, so you’ll have time to prepare. Along with some minor improvements and fixes, release 1.2 boasts a big new feature — vault liquidation. In the previous post we told you about what vault liquidation is and how to avoid it. In this post we’ll make YOU a liquidator — because in EAST.Finance anyone can become a liquidator and get WEST with a big discount!

So this is how you can liquidate an EAST vault:

1. Transfer your USDap to your account in the Waves Enterprise network. After the transaction is completed, you will see the USDap in the Tokens tab of the Waves Enterprise client.

2. Go to Waves Enterprise RunKit, and paste get_liquidable_vaults_public_script.js script in the field on the left:

const email = '';
const password = '';
const rawOutput = false;


// DO NOT EDIT PAST THIS POINT
const baseUrl = 'https://client.wavesenterprise.com';
const eastAddress = 'https://client.east.finance';

const nodeFetch = require('node-fetch');

let accessToken = '';

const fetch = async (url, options = {}) => {
let headers = options.headers || {};
if (accessToken) {
headers = {
...headers,
'Authorization': `Bearer ${accessToken}`,
};
}
return nodeFetch(url, { ...options, headers });
}

const calculateVaults = (vaults, rate) => {
return vaults.map((vault) => {
const { west_amount, east_amount, address } = vault;
const westAmount = Number(west_amount) / 10 ** 8;
const eastAmount = Number(east_amount) / 10 ** 8;

const collateral = westAmount / eastAmount * rate;
const profit = westAmount * rate - eastAmount;

return {
address,
collateral: (collateral * 100).toFixed(2) + '%',
westAmount,
eastAmount,
profit: Number(profit.toFixed(2)),
};
})
}

(async () => {
const { access_token } = await (await fetch(`${baseUrl}/authServiceAddress/v1/auth/login`, {
method: 'POST',
body: JSON.stringify({
username: email,
password,
}),
headers: { 'Content-Type': 'application/json' }
})).json();

if (access_token) accessToken = access_token;

const rawData = await fetch(`${eastAddress}/apiAddress/v1/user/liquidatableVaults`).then((res) => res.json());
const [{ value: rate }] = await fetch(`${eastAddress}/apiAddress/v1/user/oracles?streamId=000003_latest&limit=1`).then((res) => res.json());

if (rawOutput) {
return console.log(rawData);
}

const calculated = calculateVaults(rawData, Number(rate));

console.log(`Current WEST rate: ${rate}`);
calculated.sort((a, b) => b.profit - a.profit).forEach(({ address, collateral, westAmount, eastAmount, profit }) => {
console.log(`${address} - Collateral: ${collateral}, WEST: ${westAmount}, EAST: ${eastAmount}, profit: ${profit}$`);
});
})();

Enter email and password of your Waves Enterprise account between the single quotation marks in the ‘const email’ and ‘const password’ lines.

3. If you want to receive all the details about the vault subject to liquidation change ‘rawOutput’ value from ‘false’ to ‘true’. The detailed information includes vault IDs, addresses, internal IDs, amounts of WEST, EAST and USDap (RWA) inside, WEST and USDap rates, rate timestamps, and other data. If you want addresses of the vaults only, leave the values as ‘false’.

4. Press “Run” to launch the script. You will get addresses of the vaults you can liquidate.

5. Choose the vault you want to liquidate and save its address — it’s the value in the ‘address’ field of the script response.

6. Now use the liquidation script: paste liquidation_public_script.js script to Waves Enterprise RunKit:

const email = '';
const password = '';
const seedPhraseLiquidator = ''; // your seed phrase for address

const liquidAddress = ''; // target address to be liquidated


// DO NOT EDIT PAST THIS POINT
const baseUrl = 'https://client.wavesenterprise.com/';
const eastAddress = 'https://client.east.finance/';
const nodeAddress = `${baseUrl}/node-2`;

const { MAINNET_CONFIG, create: createApiInstance } = require('@wavesenterprise/js-sdk');
const nodeFetch = require('node-fetch');

let accessToken = '';

const fetch = async (url, options = {}) => {
let headers = options.headers || {};
if (accessToken) {
headers = {
...headers,
'Authorization': `Bearer ${accessToken}`,
};
}
return nodeFetch(url, { ...options, headers });
}

(async () => {
const { access_token } = await (await fetch(`${baseUrl}/authServiceAddress/v1/auth/login`, {
method: 'POST',
body: JSON.stringify({
username: email,
password,
}),
headers: { 'Content-Type': 'application/json' }
})).json();

if (!access_token) {
return console.error('Invalid credentials');
}

if (access_token) accessToken = access_token;

const { chainId, minimumFee, gostCrypto } = await fetch(`${nodeAddress}/node/config`)
.then((res) => res.json());

const wavesApiConfig = {
...MAINNET_CONFIG,
nodeAddress,
crypto: gostCrypto ? 'gost' : 'waves',
networkByte: chainId.charCodeAt(0),
minimumFee,
};

const Waves = createApiInstance({
initialConfiguration: wavesApiConfig,
fetchInstance: fetch,
});

const { address, keyPair } = Waves.Seed.fromExistingPhrase(seedPhraseLiquidator);
const { eastContractId, eastContractVersion } = await fetch(`${eastAddress}/apiAddress/config`)
.then((res) => res.json());
const { rwaTokenId, serviceAddress } = await fetch(`${nodeAddress}/contracts/${eastContractId}/config`)
.then((res) => res.json())
.then((res) => JSON.parse(res.value));
const { eastAmount } = await fetch (`${eastAddress}/apiAddress/v1/user/vault?address=${liquidAddress}`)
.then((res) => res.json());

if (!eastAmount) {
return console.error(`Address ${liquidAddress} has no vault`);
}

const liquidateTransferCall = Waves.API.Transactions.Transfer.V3({
recipient: serviceAddress,
assetId: rwaTokenId,
amount: Number(eastAmount) * 100000000,
timestamp: Date.now(),
attachment: '',
senderPublicKey: keyPair.publicKey,
atomicBadge: {
trustedSender: address,
},
});

const liquidateTransferTxId = await liquidateTransferCall.getId();

const liquidateCall = Waves.API.Transactions.CallContract.V4({
contractId: eastContractId,
contractVersion: eastContractVersion,
senderPublicKey: keyPair.publicKey,
timestamp: Date.now(),
params: [{
type: 'string',
key: 'liquidate',
value: JSON.stringify({
transferId: liquidateTransferTxId,
address: liquidAddress,
})
}],
atomicBadge: {
trustedSender: address,
},
});

try {
const result = await Waves.API.Transactions.broadcastAtomic(
Waves.API.Transactions.Atomic.V1({ transactions: [liquidateTransferCall, liquidateCall], timestamp: Date.now() }),
keyPair,
);
console.log('Broadcast docker create result: ', result)
} catch (err) {
console.error('Broadcast error:', err.data.message)
console.error('Tx id:', err.data.tx.id);
}
})();

Enter your email and password the same way as in step 2. Then enter your seed phrase and the address of the vault chosen, right between the single quotation marks in the ‘seedPhraseLiquidator’ and ‘liquidAddress’ lines. Be careful with your seed phrase.

7. Press “Run” to launch the script. The vault of your choice will be liquidated, and you will get the script output like this:

Result of EAST liquidation script

The important thing here is your transaction id. You can search for it in the Transactions tab of the Waves Enterprise client to ensure everything is ok. Also, if the transaction was successful you will see the amount of your USDap decreased, and the WEST increased.

Bear in mind that the exchange rate of the vault you choose might change during the liquidation. The rates are updated every minute. In case of the change your liquidation will not be executed.

Follow us on Telegram and contact via ask@east.finance if necessary.

--

--

EAST.Finance
EAST.Finance

The first stablecoin based on Waves Enterprise mainnet