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

@narya-ai/contracts

v0.5.0

Published

Smart contracts from Narya.ai

Downloads

16

Readme

Narya.ai | Contracts

Developping

To test and debug narya-contracts API:

# clone and prepare narya-contracts environment
git clone https://github.com/NaryaAi/narya-contracts.git
cd /path/to/narya-contracts
yarn install
yarn link

# goto target contract root
cd /path/to/target/contract/project/root
yarn link narya-contracts

Cheatcodes Extension

Basic API

we can read any var value (private | public) via following APIs.

interface VmEx is Vm {

    // read int256 variable by name
    function readInt(address target, string calldata varName) external view returns (int256);
    // read int256 variable by slot index
    function readIntBySlot(address target, uint256 index) external view returns (int256);
    // read int8 varriable by name
    function readInt8(address target, string calldata varName) external view returns (int8);
    // read int8 variable by slot index and offset
    function readInt8BySlot(address target, uint256 index, uint256 offset) external view returns (int8);
    // read uint256 variable by name
    function readUint(address target, string calldata varName) external view returns (uint256);
    // read uint8 variable by slot index
    function readUintBySlot(address target, uint256 index) external view returns (uint256);
    // read uint8 variable by name
    function readUint8(address target, string calldata varName) external view returns (uint8);
    // read uint8 by slot index and offset
    function readUint8BySlot(address target, uint256 index, uint256 offset) external view returns (uint8);

    // read raw `size` bytes by slot index and slot offset
    function readRawBytes(address target, uint256 slot, uint256 offset, uint256 size) external view returns (bytes memory);
    // read `size` bytes by variable name
    function readBytes(address target, string calldata varName, uint256 size) external view returns (bytes memory);

    // read whole int8 array data by name
    function readInt8Array(address target, string calldata varName) external view returns (int8[] memory);
    // read int8 array element at index by name
    function readInt8ArrayElem(address target, string calldata varName, uint256 index) external view returns (int8);
    // read whole int256 array data by name
    function readInt256Array(address target, string calldata varName) external view returns (int256[] memory);
    // read int256 array element at index by name
    function readInt256ArrayElem(address target, string calldata varName, uint256 index) external view returns (int256);
    // read whole uint8 array data by name
    function readUint8Array(address target, string calldata varName) external view returns (uint8[] memory);
    // read uint8 array element at index by name
    function readUint8ArrayElem(address target, string calldata varName, uint256 index) external view returns (uint8);
    // read whole uint256 array data by name
    function readUint256Array(address target, string calldata varName) external view returns (uint256[] memory);
    // read uint256 array element at index by name
    function readUint256ArrayElem(address target, string calldata varName, uint256 index) external view returns (uint256);

    function readAddressUint256MapValue(address target, string calldata varName, address key) external view returns (uint256);
    function readUint256Uint256MapValue(address target, string calldata varName, uint256 key) external view returns (uint256);

    // get 1D Array[index] slot id by variable name
    function getArraySlotIndex(address target, string calldata varName, uint256 index) external view returns (uint256);

    // get slot id by variable name
    function getVarSlotIndex(address target, string calldata varName) external view returns (uint256);
}

Same with Vm in foundry, VmEx also locate at 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D

address(bytes20(uint160(uint256(keccak256('hevm cheat code')))))

API for mapping


    // for mapping(uint256 => xx), get slot index of value
    function mapKeyUint256SlotByName(address who, string memory mapName, uint256 key) internal view returns (uint256) {
        uint256 mapSlot = vmex.getVarSlotIndex(who, mapName);
        return uint256(keccak256(abi.encodePacked(key, mapSlot)));
    }

    // for mapping(address => xx), get slot index of value
    function mapKeyAddressSlotByName(address who, string memory mapName, address key) internal view returns (uint256) {
        uint256 mapSlot = vmex.getVarSlotIndex(who, mapName);
        return uint256(keccak256(abi.encode(key, mapSlot)));
    }

Because there could be multiple definitions of mapping, we only provide basic abilities to get mapping value slot index.

Combining with readIntBySlot | readInt8BySlot | readUintBySlot | readUint8BySlot, we can get mapping value.

More complicated, Embedding mapping, for example:

Here is a embedding mapping mapping(uint, mapping(uint, uint)) embed.

Our target is to read value of embed[123][address(0x79)]:

// get slot index of internal mapping `mapping(uint, uint)` <=> embed[123]
uint slot1 = mapKeyUint256SlotByName(address(dummy), "embed", 123);
// get slot index of target value <=> embed[123][address(0x79)]
uint slot2 = mapKeyUint256SlotBySlot(address(dummy), slot1, address(0x79));
// get slot value be slot index
uint result = vm.readUintBySlot(address(dummy), slot2)

result is value of embed[123][address(0x79)].

Example

Example target contract is:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract Dummy {
    uint8 public val;
    uint256 public val256;
    uint16 public val16;
    uint8[] private array8 = [0, 1, 2];
    mapping(uint256 => uint256) private map256;
    mapping(address => uint256) private mapAddress;

    function f(uint8 _val) public {
        val = _val;
        val256 = uint256(_val);
        val16 = (uint16(_val) << 16) | uint16(_val);
        array8[0] = _val;
        map256[123] = uint256(_val);
        mapAddress[address(0x79)] = uint256(_val);
    }

    function g() public {
        val = 0;
    }
}

Our invariant is mapAddress[address(0x79)] != 23. we can implement this invariant in check() function.

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "contracts/Dummy.sol";
import "narya-contracts/PTest.sol";

contract TestPrivDummy is PTest {
    Dummy dummy;

    function setUp() public {
        dummy = new Dummy();
    }

    function check() external view override {
        //require(dummy.val() != 127, "wrong val");
        //require(vm.readInt8(address(dummy), uint256(keccak256("val"))) != 127, "wrong val");
        //require(vm.readInt(address(dummy), "val256") != 127, "wrong val");
        //require(vm.readInt8ArrayElem(address(dummy), "array8", 0) != 65, "wrong val");
        //require(vm.getVarSlotIndex(address(dummy), "array8") != 3, "wrong val");
        //uint slot = mapKeyUint256SlotByName(address(dummy), "map256", 123);
        uint slot = mapKeyAddressSlotByName(address(dummy), "mapAddress", address(0x79));
        require(vm.readUintBySlot(address(dummy), slot) != 23, "wrong val");
    }
}
  1. Get mapAddress[0x79] value slot index by api mapKeyAddressSlotByName, and store return value into slot
  2. use vm.readUintBySlot to read slot value as uint256.

Q&A

  1. Evm Revert error in trace report.

Possible Solution: check target variable type and API usage. var type should be same with API:

| variable type | API for reading variable | | :- | :- | | uint / uint256 | readUint / readUint256ArrayElem / readUint256Array | | int / int256 | readInt / readInt256ArrayElem / readInt256Array | | uint8 | readUint8 / readUint8ArrayElem / readUint8Array | | int8 | readInt8 / readInt8ArrayElem / readInt8Array |

TODO

  • [ ] Support more integer types (16 / 32 / 48 / 64, etc.)
  • [ ] adapt with a better local testing tool

Reference