diff --git a/.gitmodules b/.gitmodules index 05a2491880..383c38c67c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -533,6 +533,9 @@ [submodule "vendor/grammars/hoon-grammar"] path = vendor/grammars/hoon-grammar url = https://github.com/pkova/hoon-grammar.git +[submodule "vendor/grammars/huff-ghlang"] + path = vendor/grammars/huff-ghlang + url = https://github.com/sambacha/huff-ghlang.git [submodule "vendor/grammars/ide-tools"] path = vendor/grammars/ide-tools url = https://github.com/toitware/ide-tools.git diff --git a/grammars.yml b/grammars.yml index 23c95ad2f7..0ba3a46273 100644 --- a/grammars.yml +++ b/grammars.yml @@ -444,6 +444,8 @@ vendor/grammars/holyc.tmbundle: - source.hc vendor/grammars/hoon-grammar: - source.hoon +vendor/grammars/huff-ghlang: +- source.huff vendor/grammars/ide-tools: - source.toit vendor/grammars/idl.tmbundle: diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index aae547bd83..0ec039c2d4 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -2951,6 +2951,14 @@ Hosts File: tm_scope: source.hosts ace_mode: text language_id: 231021894 +Huff: + type: programming + color: "#707598" + extensions: + - ".huff" + tm_scope: source.huff + ace_mode: text + language_id: 405540950 Hy: type: programming ace_mode: text diff --git a/samples/Huff/Clones.huff b/samples/Huff/Clones.huff new file mode 100644 index 0000000000..3909454100 --- /dev/null +++ b/samples/Huff/Clones.huff @@ -0,0 +1,156 @@ +/// @title Clones +/// @notice SPDX-License-Identifier: MIT +/// @author Maddiaa +/// @author asnared +/// @notice https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for deploying minimal proxy contracts, also known as "clones". +/// @notice To simply and cheaply clone contract functionality in an immutable way, this standard specifies +/// a minimal bytecode implementation that delegates all calls to a known, fixed address. +/// +/// @notice The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` +/// (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the +/// deterministic method. +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol) + +// Linguist TODO: Replace the example huff files with a purpose-written file + +#include "./ERC1967Upgrade.huff" +#include "../utils/CommonErrors.huff" + +// BEFORE ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x3d | 0x36 | RETURNDATASIZE | 0 // +// 0x60 | 0x602d | PUSH1 0x2d | 0x2d 0 // +// 0x80 | 0x36 | DUP1 | 0x2d 0x2d 0 // +// 0x60 | 0x600a | PUSH1 0x0a | 0x0a 0x2d 0x2d 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0x0a 0x2d 0x2d 0 // +// 0x39 | 0x39 | CODECOPY | 0x2d 0 // +// 0x81 | 0x81 | DUP2 | 0 0x2d 0 // +// 0xf3 | 0xf3 | RETURN | 0 // + +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // +// 0x37 | 0x37 | CALLDATACOPY | // +// 0x3d | 0x3d | RETURNDATASIZE | 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 0 // +// 0x36 | 0x36 | CALLDATASIZE | size 0 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size 0 0 0 // +// 0x73 | 0x73 | PUSH20 | addr 0 size 0 0 0 // + +// AFTER ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x5a | 0x5a | GAS | gas addr 0 size 0 0 0 // +// 0xf4 | 0xf4 | DELEGATECALL | success 0 // +// 0x3d | 0x3d | RETURNDATASIZE | rds success 0 // +// 0x82 | 0x82 | DUP3 | 0 rds success 0 // +// 0x80 | 0x80 | DUP1 | 0 0 rds success 0 // +// 0x3e | 0x3e | RETURNDATACOPY | success 0 // +// 0x90 | 0x90 | SWAP1 | 0 success // +// 0x3d | 0x3d | RETURNDATASIZE | rds 0 success // +// 0x91 | 0x91 | SWAP2 | success rds 0 // +// 0x60 | 0x602b | PUSH1 0x2b | 0x2b success rds 0 // +// 0x57 | 0x57 | JUMPI | Revert if success == 0 // +// 0xfd | 0xfd | REVERT | // +// 0x5b | 0x5b | JUMPDEST | // +// 0xf3 | 0xf3 | RETURN | // +//--------------------------------------------------------------------------------// + +#define constant BYTECODE_BEFORE_ADDRESS = 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000 +#define constant BYTECODE_AFTER_ADDRESS = 0x5af43d82803e903d91602b57fd5bf3 + +/// @notice Clone a contract using `create`. +/// @param {Stack} Implementation - address of the contract to clone. +#define macro CLONE() = takes (1) returns (1) { + CLONE_MACRO(create) +} + +/// @notice Clone a contract to a deterministic address using `create2`. +/// @param {Stack} Implementation - address of the contract to clone. +/// @param {Stack} Salt - The salt to be added to create2. +#define macro CLONE_DETERMINISTIC() = takes (2) returns (1) { + CLONE_MACRO(create2) +} + +/// @dev Can remain inside the scratch space therefore no memory pointer is required +#define macro CLONE_MACRO(deploy_opcode) = takes (2) returns (1) { + // Input Stack: [implementation, salt [optional]] + + // Store the prefix + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, salt] + 0x00 mstore // [implementation, salt] + + // Place the implementation at memory byte 20 + 0x60 shl // [rightpad(implementation), salt] + 0x14 mstore // [salt] + + // Add the suffix after the implementation at byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3) // [suffix, salt] + 0x28 mstore // [salt] + + // Create the contract + 0x37 // [0x37, salt] + 0x00 // [0x00, 0x37, salt] + 0x00 // [0x00, 0x00, 0x37, salt] + // [address] * This will be create | create2 + + // Throw exception if deployment fails + dup1 iszero create_failed jumpi // [address] + continue jump + + create_failed: + DEPLOYMENT_FAILED(0x00) + + continue: +} + + +/// @dev Memory pointer required as this function nukes memory and this is part of a library +#define macro PREDICT_DETERMINISTIC_ADDRESS(ptr) = takes (3) returns (1) { + // Input Stack: [implementation, salt, deployer] + swap1 swap2 swap1 // [implementation, deployer, salt] + + // Store the creation code prefix at memory byte 0 + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, deployer, salt] + mstore // [implementation, deployer, salt] + + // Store the implementation address at memory byte 20 + 0x60 shl // [rightpad(implementation), deployer, salt] + 0x14 add // [ptr + 0x14, implementation, deployer, salt] + mstore // [deployer, salt] + + // Store the creation code suffix at memory byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3ff) // [bytecode_after, deployer, salt] + 0x28 add // [ptr + 0x28, bytecode_after, deployer, salt] + mstore // [deployer, salt] + + // mstore(add(ptr, 0x38), deployer) + 0x60 shl // [rightpad(deployer), salt] + 0x38 add // [ptr + 0x38, deployer, salt] + mstore // [salt] + + // mstore(add(ptr, 0x58), salt) + 0x4c add // [ptr + 0x58, salt] + mstore // [] + + // Hash and then store in memory + 0x37 // [0x37] + // [ptr, 0x37] + sha3 // [hash] + + 0x6c add // [ptr + 0x6c, hash] + mstore // [] + + // Hash the rest of the data + 0x55 // [0x55] + 0x37 add // [ptr + 0x37, 0x55] + sha3 // [hash] + + // Clean the upper 96 bits (12 bytes) of the hash + // The remaining 160 bits (20 bytes) are the address + 0x60 shl 0x60 shr // [clean(hash)] +} diff --git a/samples/Huff/ETHDropper.huff b/samples/Huff/ETHDropper.huff new file mode 100644 index 0000000000..e6e097b077 --- /dev/null +++ b/samples/Huff/ETHDropper.huff @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: MIT +// @author https://github.com/Philogy/mega-dropper/blob/main/src/ERC20Dropper.huff + +#define constant AMT_OFFSET = 0xa0 // 160 + +#define macro WORD_2() = takes(0) returns(2) { msize msize } +#define macro WORD_4() = takes(0) returns(4) { WORD_2() WORD_2() } +#define macro WORD_8() = takes(0) returns(8) { WORD_4() WORD_4() } +#define macro WORD_16() = takes(0) returns(16) { WORD_8() WORD_8() } +#define macro WORD_32() = takes(0) returns(32) { WORD_16() WORD_16() } +#define macro WORD_64() = takes(0) returns(64) { WORD_32() WORD_32() } +#define macro WORD_128() = takes(0) returns(128) { WORD_64() WORD_64() } +#define macro WORD_256() = takes(0) returns(256) { WORD_128() WORD_128() } +#define macro WORD_512() = takes(0) returns(512) { WORD_256() WORD_256() } + +#define macro NO_FAILS() = takes(0) returns(1) { + msize // [msize] + 0x20 // [msize, 0x20] + eq // [msize == x020] +} + +#define macro SEND_ETH() = takes(1) returns(1) { + // takes: [cd_offset] + calldataload // [send_data] + 0x0 0x0 0x0 // [send_data, 0, 0, 0] + dup4 // [send_data, 0, 0, 0, send_data] + [AMT_OFFSET] // [send_data, 0, 0, 0, send_data, offset] + shr // [send_data, 0, 0, 0, amount] + 0x0 // [send_data, 0, 0, 0, amount, 0] + swap5 // [0, 0, 0, 0, amount, send_data] + gas // [0, 0, 0, 0, amount, send_data, gas] + // Packed paramaters can directly be used as address because CALL ignores dirty bits. + call // [suc] + // returns: [suc] +} + +#define macro SEND_ETH_STEP() = takes(2) returns(1) { + // takes: [word_size, size] + sub // [size'] + dup1 // [size', size'] + SEND_ETH() // [size', suc] + // Chain `success` check, sets MSIZE to 0x40 if false. + iszero // [size', !suc] + mload // [size', _] + pop // [size'] + // returns: [size'] +} + +#define macro SEND_ETH_STEP_2() = takes(3) returns(1) { SEND_ETH_STEP() SEND_ETH_STEP() } +#define macro SEND_ETH_STEP_4() = takes(4) returns(1) { SEND_ETH_STEP_2() SEND_ETH_STEP_2() } +#define macro SEND_ETH_STEP_8() = takes(5) returns(1) { SEND_ETH_STEP_4() SEND_ETH_STEP_4() } +#define macro SEND_ETH_STEP_16() = takes(6) returns(1) { SEND_ETH_STEP_8() SEND_ETH_STEP_8() } +#define macro SEND_ETH_STEP_32() = takes(7) returns(1) { SEND_ETH_STEP_16() SEND_ETH_STEP_16() } +#define macro SEND_ETH_STEP_64() = takes(8) returns(1) { SEND_ETH_STEP_32() SEND_ETH_STEP_32() } +#define macro SEND_ETH_STEP_128() = takes(9) returns(1) { SEND_ETH_STEP_64() SEND_ETH_STEP_64() } +#define macro SEND_ETH_STEP_256() = takes(10) returns(1) { SEND_ETH_STEP_128() SEND_ETH_STEP_128() } +#define macro SEND_ETH_STEP_512() = takes(11) returns(1) { SEND_ETH_STEP_256() SEND_ETH_STEP_256() } + +#define macro MAIN() = takes(0) returns(0) { + // No ABI selector or params, only function is to transfer ETH to a bunch of addresses. + // (Address, amount) pairs should be encoded packed as (uint96, address) in 32-byte chunks. No + // ABI-style offset/length. + + + // Sets `msize = 0x20`. + 0x0 mload // [0] + + calldatasize // [0, cdz] + calldatasize // [0, cdz, cdz] + 0x4000 // [0, cdz, cdz, 1 << 14] + gt // [0, cdz, 1 << 14 > cdz] + send256 jumpi // [0, cdz] + loop512: // [0, size_left] + 0x0 // [0, size_left, 0] + mstore // [0, ] + WORD_512() // [0, 0x20 ...] + 0x0 // [0, 0x20 ..., 0] + mload // [0, 0x20 ..., size_left] + SEND_ETH_STEP_512() // [0, size_left'] + + // Do-while loop check. + dup1 // [0, size_left', size_left'] + 0x3fff // [0, size_left', size_left', 512*0x20 - 1] + lt // [0, size_left', size_left' >= 512*0x20] + loop512 jumpi // [0, size_left] + send256: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x2000 // [0, size_left, size_left, 256*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send128 jumpi // [0, size_left] + 0x0 // [0, size_left, 0] + mstore // [0, ] + WORD_256() // [0, 0x20 ...] + 0x0 // [0, 0x20 ..., 0] + mload // [0, 0x20 ..., size_left] + SEND_ETH_STEP_256() // [0, size_left'] + send128: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x1000 // [0, size_left, size_left, 128*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send64 jumpi // [0, size_left] + 0x0 // [0, size_left, 0] + mstore // [0, ] + WORD_128() // [0, 0x20 ...] + 0x0 // [0, 0x20 ..., 0] + mload // [0, 0x20 ..., size_left] + SEND_ETH_STEP_128() // [0, size_left'] + send64: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x800 // [0, size_left, size_left, 64*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send32 jumpi // [0, size_left] + 0x0 // [0, size_left, 0] + mstore // [0, ] + WORD_64() // [0, 0x20 ...] + 0x0 // [0, 0x20 ..., 0] + mload // [0, 0x20 ..., size_left] + SEND_ETH_STEP_64() // [0, size_left'] + send32: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x400 // [0, size_left, size_left, 32*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send16 jumpi // [0, size_left] + WORD_16() // [0, size_left, 0x20 ...] + swap16 // [0, 0x20 ..., size_left] + WORD_16() // [0, 0x20 ..., size_left, 0x20 ...] + swap16 // [0, 0x20 ..., size_left] + SEND_ETH_STEP_32() // [0, size_left'] + send16: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x200 // [0, size_left, size_left, 16*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send8 jumpi // [0, size_left] + WORD_16() // [0, size_left, 0x20 ...] + swap16 // [0, 0x20 ..., size_left] + SEND_ETH_STEP_16() // [0, size_left'] + send8: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x100 // [0, size_left, size_left, 8*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send4 jumpi // [0, size_left] + WORD_8() // [0, size_left, 0x20 ...] + swap8 // [0, 0x20 ..., size_left] + SEND_ETH_STEP_8() // [0, size_left'] + send4: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x80 // [0, size_left, size_left, 4*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send2 jumpi // [0, size_left] + WORD_4() // [0, size_left, 0x20 ...] + swap4 // [0, 0x20 ..., size_left] + SEND_ETH_STEP_4() // [0, size_left'] + send2: // [0, size_left] + dup1 // [0, size_left, size_left] + 0x40 // [0, size_left, size_left, 2*0x20] + and // [0, size_left, section_bit_set] + iszero // [0, size_left, skip_section] + send1 jumpi // [0, size_left] + WORD_2() // [0, size_left, 0x20 ...] + swap2 // [0, 0x20 ..., size_left] + SEND_ETH_STEP_2() // [0, size_left'] + send1: // [0, size_left] + 0x20 // [0, size_left, 0x20] + and // [0, section_bit_set] + iszero // [0, skip_section] + no_last_send jumpi // [0] + SEND_ETH() // [suc] + selfbalance // [suc, this.bal] + leftover1 jumpi // [suc] + NO_FAILS() // [suc, no_fail] + and // [no_fail] + done jumpi // [] + 0x0 0x0 // [0, 0] + revert // [] -- end + no_last_send: // [0] + selfbalance // [0, this.bal] + leftover0 jumpi // [0] + NO_FAILS() // [0, no_fails] + done jumpi // [0] + 0x0 // [0, 0] + revert // [] -- end + leftover0: // [0] + 0x0 0x0 0x0 // [0, 0, 0, 0] + selfbalance // [0, 0, 0, 0, this.bal] + caller // [0, 0, 0, 0, this.bal, msg.sender] + gas // [0, 0, 0, 0, this.bal, msg.sender, gas] + call // [suc] + NO_FAILS() // [suc, no_fail] + and // [no_fail] + done jumpi // [] + 0x0 0x0 // [0, 0] + revert // [] -- end + leftover1: // [suc1] + 0x0 0x0 0x0 0x0 // [suc1, 0, 0, 0, 0] + selfbalance // [suc1, 0, 0, 0, 0, this.bal] + caller // [suc1, 0, 0, 0, 0, this.bal, msg.sender] + gas // [suc1, 0, 0, 0, 0, this.bal, msg.sender, gas] + call // [suc1, suc2] + NO_FAILS() // [suc1, suc2, no_fail] + and // [suc1, no_fail] + and // [no_fail] + done jumpi // [] + 0x0 0x0 // [0, 0] + revert // [] -- end + done: // [...] + stop // [...] -- end +} diff --git a/samples/Huff/errors.huff b/samples/Huff/errors.huff new file mode 100644 index 0000000000..c8aa2c29b0 --- /dev/null +++ b/samples/Huff/errors.huff @@ -0,0 +1,158 @@ +/// @title Errors +/// @notice SPDX-License-Identifier: MIT +/// @author jtriley.eth +/// @author clabby +/// @notice Custom error utilities. + +// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require + +// Errors +#define error Error(string) +#define error Panic(uint256) + +// Constants +// Solidity Panic Codes +#define constant COMPILER_PANIC = 0x00 +#define constant ASSERT_FALSE = 0x01 +#define constant ARITHMETIC_OVERFLOW = 0x11 +#define constant DIVIDE_BY_ZERO = 0x12 +#define constant INVALID_ENUM_VALUE = 0x21 +#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 +#define constant EMPTY_ARRAY_POP = 0x31 +#define constant ARRAY_OUT_OF_BOUNDS = 0x32 +#define constant MEMORY_TOO_LARGE = 0x41 +#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 + +/* + +Solidity Require. Error `string` MUST be no greater than 32 bytes. + +MEMORY LAYOUT WHEN THROWN +| sig || message offset || message length || message "revert" | +0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 + +*/ +#define macro REQUIRE() = takes (3) returns (0) { + // takes: // [condition, message_length, message] + do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] + jumpi // [message_length, message] + __ERROR(Error) // [error_sig, , message_length, message] + 0x00 // [mem_ptr, error_sig, message_length, message] + mstore // [message_length, message] + 0x20 // [message_offset, message_length, message] + 0x04 // [message_offset_ptr, message_offset, message_length, message] + mstore // [message_length, message] + 0x24 // [message_length_ptr, message_length, message] + mstore // [message] + 0x44 // [message_ptr, message] + mstore // [] + 0x80 // [size] + 0x00 // [offset, size] + revert // [] + do_not_throw: // [message_length, message] + pop // [message] + pop // [] +} + +/* + +Solidity Panic. + +MEMORY LAYOUT WHEN THROWN +| sig || panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro PANIC() = takes (1) returns (0) { + // takes: // [panic_code] + __ERROR(Panic) // [panic_sig, panic_code] + 0x00 // [panic_sig_offset, panic_sig, panic_code] + mstore // [panic_code] + 0x04 // [panic_code_offset, panic_code] + mstore // [] + 0x24 // [revert_size] + 0x00 // [revert_offset, revert_size] + revert // [] +} + +/* +Solidity Assert. + +MEMORY LAYOUT WHEN THROWN +| sig || assert failed panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro ASSERT() = takes (1) returns (0) { + // takes: // [condition] + do_not_panic // [do_not_panic_jumpdest, condition] + jumpi // [] + [ASSERT_FALSE] // [assert_false] + PANIC() // [] + do_not_panic: // [] +} + +// Assert that two stack elements are equal +#define macro ASSERT_EQ() = { + // takes: [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two stack elements are not equal +#define macro ASSERT_NOT_EQ() = { + // takes: [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two memory offsets contain equal words +#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two memory offsets do not contain equal words +#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two storage slots contain equal words +#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two storage slots do not contain equal words +#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ +#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { + // takes: // [call_succeeded] + call_succeeded // [call_succeeded_jumpdest, call_succeeded] + jumpi // [] + returndatasize // [returndatasize] + 0x00 // [memory_offset, returndatasize] + returndatasize // [returndatasize, memory_offset, returndatasize] + dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] + dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] + returndatacopy // [memory_offset, returndatasize] + revert // [] + call_succeeded: +} diff --git a/vendor/README.md b/vendor/README.md index bb42a892d3..7fb84e2deb 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -249,6 +249,7 @@ This is a list of grammars that Linguist selects to provide syntax highlighting - **HiveQL:** [adidonato/language-hql](https://github.com/adidonato/language-hql) - **HolyC:** [codingdandy/holyc.tmbundle](https://github.com/codingdandy/holyc.tmbundle) - **Hosts File:** [Alhadis/language-etc](https://github.com/Alhadis/language-etc) +- **Huff:** [sambacha/huff-ghlang](https://github.com/sambacha/huff-ghlang) - **Hy:** [tshakalekholoane/vscode-hy](https://github.com/tshakalekholoane/vscode-hy) - **IDL:** [mgalloy/idl.tmbundle](https://github.com/mgalloy/idl.tmbundle) - **IGOR Pro:** [byte-physics/language-igor](https://github.com/byte-physics/language-igor) diff --git a/vendor/grammars/huff-ghlang b/vendor/grammars/huff-ghlang new file mode 160000 index 0000000000..b56c9ad8dd --- /dev/null +++ b/vendor/grammars/huff-ghlang @@ -0,0 +1 @@ +Subproject commit b56c9ad8dd512fc4cf09c116c07d5cf14d95a3a4 diff --git a/vendor/licenses/git_submodule/huff-ghlang.dep.yml b/vendor/licenses/git_submodule/huff-ghlang.dep.yml new file mode 100644 index 0000000000..71f8dac25d --- /dev/null +++ b/vendor/licenses/git_submodule/huff-ghlang.dep.yml @@ -0,0 +1,19 @@ +--- +name: huff-ghlang +version: b56c9ad8dd512fc4cf09c116c07d5cf14d95a3a4 +type: git_submodule +homepage: https://github.com/sambacha/huff-ghlang.git +license: mit +licenses: +- sources: LICENSE.txt + text: |+ + Copyright 2022 Huff-Language + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +notices: [] +...