Skip to content

Commit

Permalink
Merge pull request #589 from terra-money/fee
Browse files Browse the repository at this point in the history
Fee
  • Loading branch information
evanorti committed Nov 15, 2023
2 parents 2725295 + 1bccc57 commit d5aee76
Show file tree
Hide file tree
Showing 10 changed files with 804 additions and 350 deletions.
258 changes: 258 additions & 0 deletions docs/develop/guides/register-feeshare.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
# FeeShare registration

The [x/FeeShare module](../module-specifications/spec-feeshare.mdx) allows smart contracts to receive a portion of the gas fees generated by interactions with the contract. Use this guide to learn how to register your contract and earn a portion of transaction fees. For more information on this module, visit the [FeeShare spec](../module-specifications/spec-feeshare.mdx).

## Register an existing contract

### Using Terrad

You can use Terrad to register your contract with the following commands. Be sure to use the appropriate flags when submitting the transaction.

The following command can only be used by the contract's admin. If the contract has no admin, only the creator can use it.

```sh Terrad
terrad tx feeshare [contract] [withdraw] --from [your_address]
```

To use the command, specify the following:

- _`[contract]`_: The address of the deployed contract.
- _`[withdraw]`_: An address to which the portion of the fee revenue will be sent.
- _`[your_address]`_: The address of the signer.

### Using a JSON message

The following example is a JSON message that can be sent to register a contract address in the FeeShare module.

```json
{
"@type": "/juno.feeshare.v1.MsgRegisterFeeShare",
"contract_address": "terra1w8ta7vhpzwe0y99tvvtp7k0k8uex2jq8jts8k2hsyg009ya06qts5fwftt",
"deployer_address": "terra1880xn49l4x947pjv4a9k2qe5mf423kjzkn4ceu",
"withdrawer_address": "terra1zdpgj8am5nqqvht927k3etljyl6a52kwqup0je"
},
```

### Using feather.js

<CH.Scrollycoding>

1. In this example, the first portion of the code is used to import the [feather.js SDK](https://github.com/terra-money/feather.js), set up the accounts, and prepare the environment by initializing Terra's [Light Client Daemon](../feather-js/getting-started.mdx#2-initialize-the-lcd) and setting up the wallets and accounts.

```js Example.ts focus=1:9
import { LCDClient, MnemonicKey, MsgRegisterFeeShare } from "@terra-money/feather.js";

// Prepare environment clients, accounts and wallets
const lcd = LCDClient.fromDefaultConfig("testnet");
const mnemonic = new MnemonicKey({ mnemonic: "..." });
const deployerAddr = mnemonic.accAddress("terra");
const withdrawerAddr = mnemonic.accAddress("terra");
const wallet = lcd.wallet(mnemonic);
const contractAddr = "terra1eaxcahzxp0x8wqejqjlqaey53tp06l728qad6z395lyzgl026qkq20xj43";


(async () => {
try {
// Submit a transaction to register the feeshare
let tx = await wallet.createAndSignTx({
msgs: [new MsgRegisterFeeShare(
contractAddr,
deployerAddr,
withdrawerAddr,
)],
chainID: "pisco-1",
memo: "Registering feeshare #TerraDevs",
});
let result = await lcd.tx.broadcastSync(tx, "test-1");

console.log("Transaction Hash", result.txhash)
}
catch (e) {
console.log(e)
}
})()
```

---

2. Next, a contract is registered with the FeeShare module by executing a `MsgRegisterFeeShare` transaction. This message is created by supplying it with the following addresses:

- _`contractAddress`_: The address of the deployed contract.
- _`deployerAddress`_: The address of the deployer of the contract.
- _`withdrawerAddress`_: An address to which the portion of the fee revenue will be sent.

```js Example.ts focus=12:31

```

</CH.Scrollycoding>

## Register a new contract

Use the following example to instantiate your contract and register with the FeeShare module.

<CH.Scrollycoding>

### Setup

1. The first portion of the code is used to import the necessary functions, classes, and objects from the [feather.js SDK](https://github.com/terra-money/feather.js).


```js Example.ts mark=1:7
import { getMnemonics } from "../helpers/mnemonics";
import { getLCDClient } from "../helpers/lcd.connection";
import { Coins, Fee, MnemonicKey, MsgExecuteContract, MsgInstantiateContract, MsgRegisterFeeShare, MsgStoreCode } from "@terra-money/feather.js";
import { blockInclusion } from "../helpers/const";
import fs from "fs";
import path from 'path';

// Prepare environment clients, accounts and wallets
const LCD = getLCDClient();
const accounts = getMnemonics();
const wallet = LCD.chain1.wallet(accounts.feeshareMnemonic);
const deployerAddress = accounts.feeshareMnemonic.accAddress("terra");
const withdrawerAddress = new MnemonicKey().accAddress("terra");
let contractAddress: string;

(async () => {
// Read the reflect contract, store it on chain and
// read the code id from the result...
let tx = await wallet.createAndSignTx({
msgs: [new MsgStoreCode(
deployerAddress,
fs.readFileSync(path.join(__dirname, "/../contracts/reflect.wasm")).toString("base64"),
)],
chainID: "test-1",
});

let result = await LCD.chain1.tx.broadcastSync(tx, "test-1");
await blockInclusion();
let txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any;
let codeId = Number(txResult.logs[0].events[1].attributes[1].value);
expect(codeId).toBeDefined();

// ... then instantiate the reflect contract
// wait for the block inclusion and read the
// contract adddress from the result logs
tx = await wallet.createAndSignTx({
msgs: [new MsgInstantiateContract(
deployerAddress,
deployerAddress,
codeId,
{},
Coins.fromString("1uluna"),
"Reflect contract " + Math.random(),
)],
chainID: "test-1",
});
result = await LCD.chain1.tx.broadcastSync(tx, "test-1");
await blockInclusion();
txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1") as any;
contractAddress = txResult.logs[0].eventsByType.instantiate._contract_address[0];

// Submit a transaction to register the feeshare
tx = await wallet.createAndSignTx({
msgs: [new MsgRegisterFeeShare(
contractAddress,
deployerAddress,
withdrawerAddress,
)],
chainID: "test-1",
});

result = await LCD.chain1.tx.broadcastSync(tx, "test-1");
await blockInclusion();

// Send an execute message to the reflect contract
let msgExecute = new MsgExecuteContract(
deployerAddress,
contractAddress,
{
change_owner: {
owner: withdrawerAddress,
}
},
);
tx = await wallet.createAndSignTx({
msgs: [msgExecute],
chainID: "test-1",
fee: new Fee(200_000, "400000uluna"),
});
result = await LCD.chain1.tx.broadcastSync(tx, "test-1");
await blockInclusion();


// Query the withdrawer adddress (new owner of the contract)
// and validate that the account has received 50% of the fees
const bankAmount = await LCD.chain1.bank.balance(withdrawerAddress);
expect(bankAmount[0])
.toMatchObject(Coins.fromString("200000uluna"))
})()
```

---

2. The next few lines prepare the environment by initializing Terra's [Light Client Daemon](../feather-js/getting-started.mdx#2-initialize-the-lcd) and setting up the wallets and accounts.
```js Example.ts focus=9:14

```

---

### Deploy the contract

1. This code creates and signs a transaction to store the smart contract on the blockchain. It waits for the transaction to be completed and gets the contract's code id from the result.

```js Example.ts focus=16:31

```

---

2. A contract instantiation message is created and signed to deploy the contract to the blockchain. The contract has an initial balance of `1uluna`. It waits for the transaction to be completed and gets the contract address from the result.


```js Example.ts focus=33:50

```

---

### Register with the FeeShare module

The contract is registered with the FeeShare module by executing a `MsgRegisterFeeShare` transaction. This message is created by supplying it with the following addresses:

- _`contractAddress`_: The address of the deployed contract.
- _`deployerAddress`_: The address of the deployer of the contract.
- _`withdrawerAddress`_: An address to which the portion of the fee revenue will be sent.


```js Example.ts focus=52:63

```


---


### Check for fees

1. In this example, a transaction is created by executing the sample contract's _`change_owner`_ message along with a fee of _`400000uluna`_ for the transaction.

```js Example.ts focus=65:81

```

---

2. To check that the FeeShare is working properly, the _`withdrawer_address`_ is queried. In this code, the expected portion of fees sent to a contract's registered _`withdrawer_address`_ is _`0.500000000000000000`_, or half of the fees. If the module is working properly, half of the fees (_`200000uluna`_) are expected to be sent to the _`withdrawer_address`_.

```js Example.ts focus=84:89

```


</CH.Scrollycoding>



37 changes: 37 additions & 0 deletions docs/develop/module-specifications/spec-feeshare.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Admonition from '@theme/Admonition';

# FeeShare

<Admonition type="info" icon="ℹ️">

The FeeShare module is an open-source module created by the Juno network. This document is a stub and mainly covers Terra-specific notes on how it is used. Visit the [original documentation](https://docs.junonetwork.io/developer-guides/juno-modules/feeshare#registering-factory-contracts) for more information.

</Admonition>

The FeeShare module enables contracts to share in the distribution of fees generated from contract transactions. Whenever a transaction occurs, a gas fee is incurred and distributed to validators via the [Distribution module](./spec-distribution.mdx). With FeeShare, a portion of this fee can be diverted back to an address specified by the contract the transaction originated from. In order to participate in fee sharing, contracts must be [registered with the module](../guides/register-feeshare.mdx).

## Governance parameters

The following parameters can be adjusted by creating a [governance proposal](./spec-governance.mdx).

| Key | Type | Default Value |
| :------------------------- | :---------- | :--------------- |
| `EnableFeeShare` | bool | `true` |
| `DeveloperShares` | sdk.Dec | `50%` |
| `AllowedDenoms` | []string{} | `[]string(nil)` |

### `EnableFeeShare`

This parameter enables the module. When set to _`false`_, it will disable all feeshare capabilities.

### `DeveloperShares`

This parameter denotes the percentage of fees diverted back to a registered contract. When set at 50%, half of all fees generated will be sent to the withdraw address specified by the registered contract.

### `AllowedDenoms`

This parameter specifies which denominations will be diverted back to a registered contract. If empty, all denominations available as fees will be diverted.

## Registering a contract

To register a new or existing contract, follow the [FeeShare registration guide](../guides/register-feeshare.mdx).
2 changes: 1 addition & 1 deletion docs/develop/module-specifications/spec-token-factory.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Admonition from '@theme/Admonition';

<Admonition type="info" icon="ℹ️">

Terra's Token Factory module is an open-source module created by the Osmosis team. This document is a stub and mainly covers Terra-specific notes on how it is used. Visit the [original documentation](https://docs.osmosis.zone/osmosis-core/modules/tokenfactory/) for more information.
The Token Factory module is an open-source module created by the Osmosis team. This document is a stub and mainly covers Terra-specific notes on how it is used. Visit the [original documentation](https://docs.osmosis.zone/osmosis-core/modules/tokenfactory/) for more information.

</Admonition>

Expand Down
5 changes: 4 additions & 1 deletion docs/full-node/run-a-full-terra-node/build-terra-core.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ If you are syncing a node from genesis, you will need to use the appropriate cor
| | | 2979805 - 4711800 | v2.2.0 |
| | | 4711800 - 5994365 | v2.3.1 |
| | | 5994365 - 7316000 | v2.4.0 |
| | | 7316000 - `present` | v2.5.2 |
| | | 7316000 - 7722000 | v2.5.2 |
| | | 7722000 - `present` | v2.6.1 |




| Network Name | Network Type | Block Height Range | Core Version |
Expand Down
34 changes: 30 additions & 4 deletions docs/full-node/run-a-full-terra-node/sync.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ From here, you can [monitor the sync](#monitor-the-sync). Make sure to check on

### Phoenix mainnet

If you would like to sync your node using the Phoenix mainnet, you will need to use version `v2.0.0` of terrad up until the block height of `890000`. To sync your node from block `890000` to block `2979805`, you will need to use version `v2.1.1` of terrad. From block `2979805` until block `4711800`, use version `v2.2.0` of terrad until block `4711800`. From block `4711800` until block `5994365`, use version `v2.3.0`. From block `5994365` until block `7316000`, use version `v2.4.0`. From block `7316000` onward, use version `v2.5.2`to complete the sync.
If you would like to sync your node using the Phoenix mainnet, you will need to use version `v2.0.0` of terrad up until the block height of `890000`. To sync your node from block `890000` to block `2979805`, you will need to use version `v2.1.1` of terrad. From block `2979805` until block `4711800`, use version `v2.2.0` of terrad until block `4711800`. From block `4711800` until block `5994365`, use version `v2.3.0`. From block `5994365` until block `7316000`, use version `v2.4.0`. From block `7316000` until block `7722000`, use version `v2.5.2`. From block `7722000` onward, use version `v2.6.1` to complete the sync.

1. To switch to version `v2.0.0` of terrad, [change into your `core` directory](./build-terra-core.mdx#get-the-terra-core-source-code) and execute the following commands in your terminal:

Expand Down Expand Up @@ -337,7 +337,7 @@ terrad start

Syncing will halt at block `5994365`, at which point you will need to change the version of terrad and then resume the syncing process.

11. To sync your Phoenix mainnet node from block `5994365` to the most recent block, you will need to navigate to the `core` directory and change your terrad version to `v2.4.0`.
11. To sync your Phoenix mainnet node from block `5994365` until block block `7316000`, you will need to navigate to the `core` directory and change your terrad version to `v2.4.0`.

```sh Terminal
git checkout v2.4.0
Expand All @@ -360,7 +360,7 @@ terrad start

Syncing will halt at block `7316000`, at which point you will need to change the version of terrad and then resume the syncing process.

13. To sync your Phoenix mainnet node from block `7316000` to the most recent block, you will need to navigate to the `core` directory and change your terrad version to `v2.5.2`.
13. To sync your Phoenix mainnet node from block `7316000` until block block `7722000`, you will need to navigate to the `core` directory and change your terrad version to `v2.5.2`.

```sh Terminal
git checkout v2.5.2
Expand All @@ -375,8 +375,34 @@ terrad version

The result of this command should be `v2.5.2`.

14. Now, you can resume the syncing process:

14. Now, you can resume and finalize the syncing process:
```sh Terminal
terrad start
```

Syncing will halt at block `7316000`, at which point you will need to change the version of terrad and then resume the syncing process.




15. To sync your Phoenix mainnet node from block `7722000` to the most recent block, you will need to navigate to the `core` directory and change your terrad version to `v2.6.1`.

```sh Terminal
git checkout v2.6.1
make install
```

Again, make sure that you have switched to the correct version of terrad by running the following command:

```sh Terminal
terrad version
```

The result of this command should be `v2.6.1`.


16. Now, you can resume and finalize the syncing process:

```sh Terminal
terrad start
Expand Down
Loading

0 comments on commit d5aee76

Please sign in to comment.