Code Monkey home page Code Monkey logo

gemfab's Introduction

Gem is an ERC20 token implementation. GemFab is a token factory that builds Gems.

The idea is to stop deploying tokens directly, and use a factory for all tokens.

Gem is not safe for extension via inheritance. Instead of customizing your gem via inheritance, you should use the built-in mint and burn, with multi-owner ward for authentication.

Minting and burning from a controller contract which defines the rules for when those can occur is the most 'hygenic' way to implement all forms of tokenomics.

If you check gemfab.built(gem), you know that gem is a Gem -- no further audit needed. An independently deployed Gem will not appear in the factory's record of valid gems, which will complicate verification for no reason. More importantly, having a record that the gem was built from the factory allows other contracts to infer that certain invariants are maintained, which a codehash check cannot satisfy because contracts can write to their state during construction time.

Here are some other implementation choices made for Gem.

  • name and symbol are bytes32 instead of string, this prevents "return data bombs" when gemfab is composed into other systems
  • Infinite allowance via approve(code, type(uint256).max);. This avoids a useless store and is a major gas savings.
  • permit -- There are several minor variations in the wild; this one uses EIP-2612 (notably, has a small difference from earlier permit in Dai).
  • Custom error types for all possible error conditions, with a consistent error API.
  • Invariants preserved with controlled mint/burn means unchecked blocks can be used to save gas in every function.
  • Functions are payable, saving a little bit of gas. The contract as a whole will still reject ether sent to invalid ABIs, including regular ether "send" (call with no calldata), which covers the most common mistake.

Working with gemfab

(Note: No packs are published yet -- watch for 'release' branch). See pack/gemfab_<network>.dpack.json to get the gemfab object plus Gem and GemFab types. See dpack for docs on how to use these packs.

Discussion

"ERC20" is an ABI definition masquerading as a semantic spec. There is no "standard ERC20". As a result, the token ecosystem is a disaster. In an ideal world, this would have been the lesson that taught EIP enthusiasts to stop doing design by committee.

Packs

Arbitrum One bafkreibhkoqc5nda6dlubyvsylethk5nxqynjltnsxnlmpc7inpcmiveom Sepolia Arbitrum Sepolia bafybeigm6cpsg4jfnh3sqezpcp77i7ted4hawmj2bybqsqgh24ot7aijva Arbitrum Goerli bafybeifbn66p32bgd36kgf5xg67fthdyjhywfywjwwg357xnlvgxr4ne5a

gemfab's People

Contributors

kbrav avatar nmushegian avatar stobiewan avatar dmfxyz avatar transmissions11 avatar

Stargazers

 avatar  avatar Omar Farooq avatar  avatar  avatar Dist Bit avatar Sarang Parikh avatar indigo avatar ZT avatar defi jesus avatar ⚡️0xO0O0⚡️ avatar Stefan Jacobs avatar sudo rm -rf --no-preserve-root / avatar Koda avatar Hilliam T. avatar ross avatar Rajiv Patel-O'Connor avatar Michael Demarais avatar sam bacha avatar Austin Green avatar  avatar

Watchers

 avatar Michael Demarais avatar  avatar  avatar sam bacha avatar  avatar

gemfab's Issues

see if making `name` and `symbol` a `bytes32` breaks common read use cases

If possible it would be nice to make these bytes32 so that it dmap auto registration thing is less annoying

Because return values are not part of ABI, it should be accessible with the same call
But possibly interpreting the return value might give weird results, we should test it out and see what etherscan shows for bytes32 symbols

`bytes32 info`

in constructor provide a bytes32 info, this is open to interpretation by creator, could be a file hash or dmap slot

Remove some entrypoints for gas savings

E.G., PERMIT_TYPEHASH is exposed as a function since it is public, but this adds entrypoints. Since solidity gives us no control over the order of these functions in the initial jump table, this might be adding extra gas.

Make js utility to extract and make sense of Caller events

  • Gem emits an extra event inside the transferFrom call which makes it possible to determine the caller (the cause of the transfer of funds) from the event logs:
    assembly{ log1(caller(), 0, 0) }
  • To help make sense of Gem, we should provide a small utility that translates the combination of Transfer and anonymous events into sensible TransferFrom "events"
  • To get a set of "TransferFrom" events for a particular caller:
    • Get all events where indexed event arg 1 (the second argument) is empty - these are the anonymous Caller events whose argument 0 is the caller
    • The immediately prior event (by absolute index) is the "Transfer" event with the rest of the information for the corresponding TransferFrom
  • To get a set of all transfers and organize "TransferFrom" events based on cause
    • Get all Transfer events for the gem for the given block
    • For each Transfer event
      • if the event immediately following (by absolute index) is the anonymous Caller event, mark this "TransferFrom" as a transferFrom
      • if it is any other event, mark this "TransferFrom" as a transfer, and the caller is the src.

Consider adding `Caller` event

The world-famous ERC20 standard does not emit information about which address called the contract, even for transferFrom where that address is critical for making sense of token flows.

We can stay compatible with ERC20 by just adding a Caller(address caller) event right before xfer/mint/burn

coverage

e.g. mint/burn have no underflow/overflow tests

`halt` function

Gem is defined as haltable or not in constructor, cannot be modified after (mutable haltable can be emulated with controller).
Some tokens will need this for compliance (e.g. USD-backed IOUs), others will not, we can support both. Can define a non-haltable token with appropriate controller contract.

✂️ Remove Mint/Burn Events

Most dapps expect Transfer() with address(0) as flag for mint or burn. This will help adoption of gem and reduce code.

remove aliases

fewer entrypoints and also can make the other functions external

`payable` for gas savings

Make functions cheaper by not rejecting ETH in function calls? Not like any other token gets rejected...

clean up dependencies

I think importing some of the OZ tests required adding a bunch of fat dependencies which npm complains about being old and insecure

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.