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

scuffed-abi

v1.0.9

Published

Package for modifying ABI encoded data. Mostly useful for testing failure cases of ABI decoders.

Downloads

1,657

Readme

Scuffed ABI

Package for modifying ABI encoded data. Mostly useful for testing failure cases of ABI decoders.

Given an ethers Contract object, you can build a scuffed contract using the function getScuffedContract.

This will return an object whose keys are the contract's function and which take the same input parameters as their associated functions.

Calling one of these functions will return an object mirroring the structure of the input parameters, with a ReplaceableOffsets object for each value's head, tail or length, as well as parameters for all nested values. See types for more information on data types.

The ReplaceableOffsets type has a function replace which allows you to replace a value after it's been encoded.

Example

Suppose we have the function:

struct SignedTransfer {
  address to;
  uint256 value;
  bytes signature;
}

function validateSignatures(SignedTransfer[] calldata transfers) external;

Then we can use scuffed abi like so:

const scuffed = getScuffedContract(contract);
const scuffedFnCall = scuffed.validateSignatures([{
  to: wallet.address,
  value: 1000,
  signature: sign(defaultAbiCoder.encode(['address', 'bytes'], [wallet.address, 1000]))
}]);
// Modify the offset to the `transfers` array
scuffedFnCall.transfers.head.replace(0x20)
// Modify the length of the signature in the first transfer
scuffedFnCall.transfers[0].signature.length.replace(0x40)
// Modify the offset to the first transfer
scuffedFnCall.transfers[0].head.replace(0)
// Modify `value`
scuffedFnCall.transfers[0].value.replace(500)
// Encode the function calldata
const data = scuffedFnCall.encode()

Types

type ReplaceableOffsets = {
  relative: number;   // position of the parameter relative to its parent
  absolute: number;   // absolute position of the parameter in the encoded args
  replace: (value: BigNumberish) => string; // replace the value in the encoded args
}

Dynamic values will have:

type DynamicOffsets = {
  head: ReplaceableOffsets;
  tail: ReplaceableOffsets;
}

Arrays and bytes parameters will have an additional length: ReplaceableOffsets field.

Static parameters will simply have the ReplaceableOffsets type without a head or tail.

Example

In the example code above, the scuffedFnCall will be structured as:

{
  encode: () => string // Encode the function call with all updated parameters
  encodeArgs: () => string // Encode the input parameters without the selector
  execute: () => Promise<Transaction> // Execute the transaction with the updated parameters
  call: () => Promise<string> // Call the function with the updated parameters
  transfers: {
    length: ReplaceableOffsets
    head: ReplaceableOffsets
    tail: ReplaceableOffsets
    '0': {
      head: ReplaceableOffsets
      tail: ReplaceableOffsets

      to: ReplaceableOffsets
      value: ReplaceableOffsets

      signature: {
        length: ReplaceableOffsets
        head: ReplaceableOffsets
        tail: ReplaceableOffsets
      }
    }
  }
}