npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@1inch/token-plugins

v1.3.0

Published

ERC20 extension enabling external smart contract based plugins to track balances of those users who opted-in to those plugins

Downloads

865

Readme

Token Plugins

Build Status Coverage Status NPM Package

Overview

This library introduces an extendable and secure system for ERC20-based tokens, inspired by the plugin concept widely used in the web 2.0 world. By subscribing an account to various plugins, users can dynamically enhance the functionality of their tokens.

Technically plugins are a collection of smart contracts that track changes in ERC20 token balances and perform supplementary accounting tasks for those balances. They are particularly useful when you need to track, for example, token shares without actually transferring tokens to an accounting contract.

How does it work and what can I extend?

Each time a balance of a connected account changes, the token contract notifies all plugins that the account has subscribed to. Each plugin implements the _updateBalances function, which is called on mint, burn and transfer, and includes change information like from and to addresses and amount. This way a plugin can perform necessary actions according to its logic to extend the base token functionality.

Keep in mind that the plugin's processing logic consumes additional gas, and operations that change an account balance will be more expensive in terms of gas. To reduce the gas impact the library implements a limit on the amount of gas that a plugin can spend and an account owner can choose which plugins to subscribe his account to.

Picture 1. Possible interactions

Implementation examples

The examples of already implemented token-plugins

  • FarmingPlugin - The 1inch staking reward farming is based on this plugin. This plugin introduces farming without the need for asset transfer or locking on a farm. An account owner can join the farm by simply adding this plugin to their account. The plugin handles all necessary accounting for joined farmers and distributes rewards based on the actual farming token balance of the account during the farming period. This is particularly useful for non-transferable tokens, for example such as debt tokens in lending protocols.
  • DelegatingPlugin - The 1inch fusion mode resolver delegation is based on this plugin. This plugin allows an account balance to be delegated to another address. This can be beneficial for governance tokens if an account owner wants to delegate their voting power to another account without a physical token transfer. The owner can recall or redelegate their delegation at any time without locking their tokens in a governance contract.

Security and limitations

The plugin system operates under the assumption that an account may subscribe to a malicious plugin. That is the reason why the following restrictions apply:

  • If a plugin fails its execution and reverts, it won't impact the main flow. The failed plugin is bypassed, and execution continues.
  • Each plugin has a gas limit set by the parent contract. If there is insufficient gas, it won't affect the main flow's execution.
  • An account can have a limited number of plugins connected, set by host contract.
  • Plugins are executed in the context specified in their contract (parent contract uses a call, not delegatecall).
  • Plugins cannot alter the calling contract state
  • Plugins cannot be reentered

Integrating plugin support in your token implementation

To integrate plugins in a smart contract, a "mothership" or parent contract have to be used to manage all related pods. This includes adding, removing, and viewing pods, as well as connecting multiple pods. The parent contract calls the updateBalance function for each pod on every update of an account’s balance. The pod then executes its logic based on the updated balance information. And then an account has to connect plugin to the account to utilize its logic.

  1. Inherit token: contract MyToken is ERC20Plugins { ... }

    Or wrap it: contract MyWrapper is ERC20Wrapper, ERC20Plugins { ... }

    This will add support for the plugin infrastructure.

  2. Wallets can plugin: MyToken.addPlugin(plugin), where plugin is address of your and third-party deployed plugin.

  3. Now every time wallet balance is change the plugin will know about it

How to create your own plugin

To create your own plugin it is necessary to inherit Plugin contract and implement its abstract function _updateBalances.

  1. Inherit plugin: contract MyPlugin is Plugin { ... }
  2. Implement _updateBalances function to process wallet balance changes

Examples of token and plugin

Below is the example of token implementing plugin support and a simple plugin that mints and burns its own token based on the parent’s token balance

// Simple token contract with plugin support
contract HostTokenExample is ERC20Plugins {
    constructor(string memory name, string memory symbol, uint256 maxPluginsPerAccount, uint256 pluginCallGasLimit)
        ERC20(name, symbol)
        ERC20Plugins(maxPluginsPerAccount, pluginCallGasLimit)
    {} // solhint-disable-line no-empty-blocks

    function mint(address account, uint256 amount) external {
        _mint(account, amount);
    }
}

// Simple plugin
contract PluginExample is ERC20, Plugin {
    constructor(string memory name, string memory symbol, IERC20Plugins token_)
        ERC20(name, symbol)
        Plugin(token_)
    {} // solhint-disable-line no-empty-blocks

    function _updateBalances(address from, address to, uint256 amount) internal override {
        if (from == address(0)) {
            _mint(to, amount);
        } else if (to == address(0)) {
            _burn(from, amount);
        } else {
            _transfer(from, to, amount);
        }
    }
}