# on ctokens, aurora, hardhat forks

By [bt3gl's symposium](https://paragraph.com/@go-outside) · 2022-09-20

---

tl; dr
------

today i go over [aurora](https://www.aurorachain.io/) on hardhat shenanigans and [compound’s](https://compound.finance/) ctoken smart contract frolicsomeness.

* * *

🎶 today’s mood
---------------

[https://open.spotify.com/track/4NlgvYgF7rny6rt17WCmGf?si=ac3dc59ff3ab4473](https://open.spotify.com/track/4NlgvYgF7rny6rt17WCmGf?si=ac3dc59ff3ab4473)

* * *

The **Compound Protocol** is an Ethereum smart contract for supplying or borrowing assets. Accounts supply capital (ether or ERC-20 tokens) to receive [**cTokens**](https://docs.compound.finance/v2/ctokens/) or borrow assets from the protocol with other collateral assets.

Each asset supported by the Compound Protocol is integrated through a cToken contract, an [**EIP-20**](https://eips.ethereum.org/EIPS/eip-20) compliant representation of balances supplied to the protocol, and is assigned a rate and a risk model. **CTokens** contains **CErc20** and **CEther** as public interfaces for ERC20 tokens and ether.

These are beautiful smart contracts, but like any code, they can carry some intriguing edge cases. Looking at the [**Compound’s cTokens contract**](https://github.com/compound-finance/compound-protocol/blob/master/contracts/CToken.sol#L293-L300), an interesting boundary condition happens when `cToken.totalSupply == 0.`

For context, the total supply of a coin includes only the coins that were already produced minus the units that were destroyed (for instance, in coin burn events).

When we look at the contract, we realize that if, for some reason, the total supply of the token goes to zero, then the exchange rate would depend on an input parameter called `initialExchangeRateMantissa`:

![](https://storage.googleapis.com/papyrus_images/3f18392bf6fd2a655f31f9f78fbbcd14ff6789d106e57ea247d64080891a12c5.webp)

* * *

Aurora on Hardhat
-----------------

We all know how popular the Compound protocol is. We all know that many sidechains implement the same concepts and primitives as the ones found in Ethereum - sometimes reproducing many parts of the original smart contracts.

[**Aurora**](https://aurora.dev/) is an Ethereum Virtual Machine (EVM) built on the [**NEAR Protocol**](https://medium.com/dia-insights/hello-near-protocol-dia-oracles-now-available-natively-on-near-3bbef5b3f13), with Ethereum as its native token. With Aurora’s EVM, Ethereum native applications can be ported to NEAR’s L2 network, which is built as a smart contract on NEAR. Some non-custodial liquidity protocols in Aurora are [Aurigami](https://www.aurigami.finance/) and [WePiggy](https://wepiggy.com/).

> 💡 _How would I test submissions (PoCs and smart contracts) for these projects without testing code on public testnets or mainnets?_

There are several development environment tools and tricks that I will be talking about in future posts (I am a nerd; I like to try and test all the things). But for this first post, we will be working with the good ol’ [**Hardhat**](https://hardhat.org/), the popular Ethereum development environment.

In the last part of this post, let’s go over some tricks when deploying and interacting with the Solidity smart contracts on Aurora using Hardhat.

### Forking a specific block

Hardhat will, by default, fork from the latest Ethereum mainnet block. However, often, a test suite might depend on forking a particular block number. Additionally, pinning a specific block enables caching and speed improvements, since if you don't pin the block, new data will be fetched with each new block.

For this setup, you will need access to a node with archival data, such as [**Alchemy**](https://www.alchemy.com/) or [Infura](https://infura.io/) or [any in this list](https://ethereumnodes.com/). Create an account and grab the RPC URL and API key.

To pin a block number, you can either simply add the info into the **hardhat.config.js** file:

![](https://storage.googleapis.com/papyrus_images/656c3b04707dcf0d603acbcdc313e2976bffac1ebf604307b7c89ba85ae77a7f.webp)

Or, if you are using a node task, you can specify a block number with the **\--fork-block-number** flag:

    npx hardhat node --fork <node provider url> --fork-block-number <block number>
    

To confirm that you have forked the latest block from Ethereum mainnet, you can send the following curl request:

    $ curl --location --request POST 'localhost:8545/' --header 'Content-Type: application/json'  --data-raw '{ "jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":83 }'
    

You  should receive a response like:

    {"jsonrpc":"2.0","id":83,"result":"0xf1ed3"}
    

Use a [**Hex converter**](https://www.rapidtables.com/convert/number/hex-to-decimal.html) to retrieve the block number.

### Setting up Aurora Network

This session is partially based on Aurora’s official guide, found [here](https://doc.aurora.dev/interact/hardhat). To set up Aurora in Hardhat, clone their ERC-20 examples:

    git clone https://github.com/aurora-is-near/aurora-examples.git  
    cd aurora-examples/hardhat/erc20/
    

Now, let’s set up Hardhat from this folder (you can start a new Hardhat project there).

Place the contract with the proof of concept inside **contracts/** and the deployment script inside **scripts/**.

By the way, this is a simple deployment script that I use often:

![](https://storage.googleapis.com/papyrus_images/bfe2095dca2bc2e185a594e650648608cac723fa5e25b6908b890acb1dda3763.webp)

Finally, add the Aurora network configuration to **hardhat.config.js**. For private keys in localhost, you can copy the values provided by Hardhat accounts. Note that I am adding Aurora’s mainnet and testnet as well. However, we will only use `aurora_local`, the `defaultNetwork`:

![](https://storage.googleapis.com/papyrus_images/59cff21cd0b5c15361b6e9d93883f23c26e19ed1e082eab5ef660dc90f775103.webp)

We are ready to run things. Let’s compile the contract:

    $ npx hardhat compile
    

And deploy it with:

    $ make deploy NETWORK=aurora_local
    

which is the same as:

    $ npx hardhat run scripts/deploy.js --network aurora_local
    

Now that the contract is deployed, you may interact with it the way you like. I use the Hardhat console often:

    $ npx hardhat console
    > const Contract = await ethers.getContractFactory('<contract name>');
    > const c = await Contract.attach('<contract address>')
    > await c.someFunction()
    

* * *

**◻️ motherofbots.eth**
-----------------------

---

*Originally published on [bt3gl's symposium](https://paragraph.com/@go-outside/on-ctokens-aurora-hardhat-forks)*
