Tutorial: How to collect fees from the Astroport Maker contract using Terra.js

Astroport
6 min readJul 8, 2022

When a user swaps tokens on Astroport, they pay a swap fee. Part of the fee goes to liquidity providers; another part goes to xASTRO holders (ASTRO stakers). For xASTRO holders, fees are used to buy ASTRO on the open market and are deposited into the xASTRO staking pool. Over time, each xASTRO becomes convertible for more ASTRO than was originally staked.

As a decentralized protocol, anyone has the ability to call the buy back function to swap fees and deposit ASTRO into the staking contract. Currently, Astroport does not support this function in the front-end UI, so users will need to call the smart contracts directly. This tutorial will go over how to interact with the Astroport Maker contract to execute this function using Terra.js.

1. Set up

Note that we have covered this section in our previous two tutorials. With the move to Terra 2.0, most of the setup remains unchanged, but there are some differences.

Prerequisites

This tutorial uses the latest stable versions of node.js and node package manager. For more information on node.js, visit https://nodejs.org.

Installing Terra.js

Open your terminal and change the directory to whichever folder you will save your project on.

cd Desktop

Make a new folder for your project and change the directory to your new folder.

mkdir maker-tutorial
cd maker-tutorial

Initialize a package.json file and node modules. You will be prompted to approve metadata for your project.

npm init

Install terra.js.

npm install --save @terra-money/terra.js

Export node options for async functions to execute properly with terra.js (only for Mac users).

export NODE_OPTIONS=--openssl-legacy-provider

Getting started with Terra.js

Open up your project folder in a code editor and create an index.js file. Terra.js reads this as the root file which will be used to execute node commands in the terminal.

For this tutorial, you will need the following modules in your index.js file:

  • LCDClient to connect to the Terra blockchain
  • MnemonicKey to sign and confirm transactions
  • MsgExecuteContract to process and execute messages
// required modules
const { LCDClient, MnemonicKey, MsgExecuteContract } = require('@terra-money/terra.js');

To get started, you will need to connect to the Terra blockchain. We will be using the new pisco-1 testnet for the Terra 2.0 network, but you can also use the new mainnet (phoenix-1) or a localterra network. For more information, visit here.

// connecting to terra blockchain
const terra = new LCDClient({
URL: 'https://pisco-lcd.terra.dev',
chainID: 'pisco-1',
});

After you’ve connected to the Terra blockchain, you will need to input a 24-word mnemonic key and set up a terra.wallet to sign and confirm transactions. Note that this is the quickest way to get started, but it leaves your private key exposed on your current file. For enhanced security, consider a hardware security key, keyring, or hosting your key on a separate encrypted file.

// wallet information
const mk = new MnemonicKey({
mnemonic: ''
});
const wallet = terra.wallet(mk);

This is how the complete setup looks:

// ** SET UP ** //// required modulesconst { LCDClient, MnemonicKey, MsgExecuteContract } = require('@terra-money/terra.js');// connecting to terra blockchain
const terra = new LCDClient({
URL: 'https://pisco-lcd.terra.dev',
chainID: 'pisco-1',
});
// wallet information
const mk = new MnemonicKey({
mnemonic: ''
});
const wallet = terra.wallet(mk);

2. Collecting fees from the Maker contract

To collect fees from a pool and swap them to ASTRO within the Maker contract, you will need to call the “collect” function. For convenience, set up a “contract_address” variable with the address of the contract you are currently working with (in this case, the Astroport Maker contract). This tutorial uses the testnet address. For a full list of addresses, look here.

// maker testnet address
const contract_address = 'terra146ffs60x8seza3cq9a447mhw0zqeylkj37ye4uj7rl2uwhvgq89sts2ess'

The Maker contract collects fees from each Astroport pair (according to the factory’s maker_fee) and tries to swap them to ASTRO. The ASTRO received from each swap is sent to xASTRO stakers (according to the governance_percent).

Any address can execute the collect operation to swap all the available fee token balances to the ASTRO token and send ASTRO to stakers.

The collect function takes in the type of assets in the pool. The info parameter for each asset in a pair can include a CW-20 token (contract_addr) or a native_token denomination (denom). Finally, the function is wrapped in an execute variable which also contains your wallet information and the contract we are working with:

// maker collect function
const execute = new MsgExecuteContract(
wallet.key.accAddress, // sender
contract_address, // contract account address
{
"collect": {
"assets": [
{
"info": {
"token": {
"contract_addr": "terra167dsqkh2alurx997wmycw9ydkyu54gyswe3ygmrs4lwume3vmwks8ruqnv"
}
}
},
{
"info": {
"native_token": {
"denom": "uluna"
}
}
}
],
}
}, // handle msg
);

To complete the call, you need an async function that creates and signs the transaction with your wallet. The “msgs” parameter takes in the execute variable we created above which contains our wallet information, the “contract_address” we are working with, and the ExecuteMsg (“collect”) to call.

const start = async function () {
const executeTx = await wallet.createAndSignTx({
msgs: [execute]
})
.then(tx => terra.tx.broadcast(tx))
.then(result => {
console.log(result.txhash)
});
}
start();

To execute the call, we use the terminal and node.js to return the transaction hash.

node index.js

Returns:

C3C3C6C35C5F9C49CECD4C6A5CC2BD79884E0CACC08D5D68732916EAF22C8AFA

Congrats! You’ve collected fees from the Maker contract! We can use the transaction hash to get more information about our transaction using a Terra explorer like terra.finder.money

You can select “Show Logs” to expand the transaction details. The “wasm” section will display the collection, swapping, and transfer of tokens for ASTRO stakers.

3. Maker Queries

config

Returns information about the Maker configuration:

// query config params
const query = terra.wasm.contractQuery(
contract_address,
{
"config": {}
} // query msg
).then(result => { console.log(result) });

To execute the query, we use the terminal and node.js:

node index.js

Returns:

{
owner: 'terra190fxpjfkp6cygr2k9unzjurq42dyehqd579h5j',
astro_token_contract: 'terra167dsqkh2alurx997wmycw9ydkyu54gyswe3ygmrs4lwume3vmwks8ruqnv',
factory_contract: 'terra1z3y69xas85r7egusa0c7m5sam0yk97gsztqmh8f2cc6rr4s4anysudp7k0',
staking_contract: 'terra19t8ffmz6q2rdm3rllyksd6sex6n650a4anttzzvz9mf8mqr4nkrq44cyu6',
governance_contract: null,
governance_percent: '0',
max_spread: '0.5',
remainder_reward: '759941404',
pre_upgrade_astro_amount: '759941404'
}

balances

Returns the balances for each specified fee token accrued by the Maker contract:

// query balances
const query = terra.wasm.contractQuery(
contract_address,
{
"balances": {
"assets": [
{
"token": {
"contract_addr": "terra167dsqkh2alurx997wmycw9ydkyu54gyswe3ygmrs4lwume3vmwks8ruqnv"
}
},
{
"native_token": {
"denom": "uluna"
}
}
],
}
} // query msg
).then(result => { console.log(result) });

To execute the query, we use the terminal and node.js:

node index.js

Returns:

{ balances: [ { info: [Object], amount: '759941404' } ] }

4. Congrats! You’ve completed the Maker contract tutorial!

For more information regarding Astroport smart contracts, visit the Astroport docs.

Follow Astroport on Twitter and subscribe to the Astroport email newsletter to get the latest alerts from the mothership.

DISCLAIMER

Any mention of third-party protocols is not an endorsement. As always, DYOR. This article does not constitute investment advice. Before interacting with Astroport, review the project disclaimers here.

--

--

Astroport

An automated, decentralised exchange protocol on the Terra blockchain. http://astroport.fi