Creating an extension

Example extension for Compound protocol.

Complete code can be found on our Github.

Below is an example of an extension. This extension interfaces with the Compound protocol and enables the NFT owner to take a loan, supply assets, repay loan and redeem cTokens from the Compound protocol.

Interfaces

First we need to define a couple of interfaces so that our NFT can talk to Compound. Functions in these interfaces are specific to the Compound protocol. They are obtained from Compound protocol docs and examples from their Github.

interface CToken {
function mint() external payable;
function mint(uint256) external returns (uint256);
function exchangeRateCurrent() external returns (uint256);
function supplyRatePerBlock() external returns (uint256);
function redeem(uint) external returns (uint);
function redeemUnderlying(uint) external returns (uint);
function borrow(uint256) external returns (uint256);
function borrowRatePerBlock() external view returns (uint256);
function borrowBalanceCurrent(address) external returns (uint256);
function repayBorrow() external payable;
function repayBorrow(uint256) external returns (uint256);
}
interface Comptroller {
function markets(address) external returns (bool, uint256);
function enterMarkets(address[] calldata) external returns (uint256[] memory);
function getAccountLiquidity(address) external view returns (uint256, uint256, uint256);
}

These interface functions allow the NFT to supply and borrow assets, repay loans and redeem cTokens.

Implementation

Now, we create the Compound NFT that inherits from the base ERC20Vault.

contract CompoundNFT is ERC20Vault { .... }

Next, we define functions specific to this NFT. Notice how all functions use 'onlyOwner' modifier restricting access to only the owner of the NFT. This can be changed to anyone with valid signature, so that the owner can delegate management functions to other wallets/contracts. Refer to EIP 712 and EIP 1271 on how this can be done. An example is here. The modifier can also be 'ownerOrSignature' to allow both modes.

function supplyEth(args...) public payable onlyOwner {
// implementation
}
function supplyErc20(args...) public onlyOwner {
// implementation
}
function redeemCTokens(args...) public onlyOwner {
// implementation
}
function borrowEth(args...) public onlyOwner {
// implementation
}
function borrowErc20(args...) public payable onlyOwner {
// implementation
}
function repayBorrowedETH(args...) public onlyOwner {
// implementation
}
function repayBorrowedERC20(args...) public onlyOwner {
// implementation
}

And, that's it. We have created an NFT extension that interfaces with the Compound protocol.

UI

Here's how the NFT frontend looks. It has multiple screens. UI with user flows can be seen on NFT Company.

Display screen
Dashboard
Supply
Borrow
Assets
Display screen
Dashboard
Supply
Borrow
Assets

Advantages

Now, crypto users have a new UI to compound. One that is better than existing UIs in a few ways:

  • Assets are segregated and siloed - no more wallet draining hacks. Assets in the NFT can only be used to invest in the NFT's underlying protocol.

  • Easy transferability of investments - gifting/transferring/selling an investment is a simple as sending the NFT to a different address. NFT owner has sole control over the assets in the NFT and its interactions with the underlying protocol.

  • Better tracking of DeFi interactions. All NFTs belonging to a user can be displayed in a single dashboard and all the interactions with DeFi protocols can be tracked as contract txns on the NFT.

Conclusion

This tutorial shows an example of an NFT extension - one that interfaces with the Compound protocol. Similar extensions can be built for other protocols like Aave, Uniswap, Sushi, Liquity, Alchemix, Pool Together, Element Finance etc. Extensions can be built for non-finance application too - like gaming, governance, social media etc. What developers can build is only limited by their imagination.