diff --git a/.gitmodules b/.gitmodules index 9337666..47db3b8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ -[submodule "lib/forge-std"] - path = lib/forge-std - url = https://github.com/foundry-rs/forge-std [submodule "lib/solady"] path = lib/solady url = https://github.com/vectorized/solady [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/README.md b/README.md index 4672d20..2d9779c 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,17 @@ #

SnakeFi - Decentralize Exchange incentive Ve(3,3)

-**Template repository for getting started quickly with Foundry projects** +## Deployment -![Github Actions](https://github.com/foundry-rs/forge-template/workflows/CI/badge.svg) +The deployer address: -## Getting Started + - EVM: `0x1cb3D844C968D30E80babe134B299BE2c66d899e` -Click "Use this template" on [GitHub](https://github.com/foundry-rs/forge-template) to create a new repository with this repo as the initial state. + - Westend Asset Hub: `5CiLd61pypFCa8uDND1S6XihW6PNF8SSirnBns4BoHJ4JvmU` -Or, if your repo already exists, run: +This is the list of deployed contract, consists of: -```sh -forge init -forge build -forge test -``` + - WrappedWND contract: -## Writing your first test + - EVM address: `0xb576972a36f18365ECE226C29b3564F4bf79CFaD` -All you need is to `import forge-std/Test.sol` and then inherit it from your test contract. Forge-std's Test contract comes with a pre-instatiated [cheatcodes environment](https://book.getfoundry.sh/cheatcodes/), the `vm`. It also has support for [ds-test](https://book.getfoundry.sh/reference/ds-test.html)-style logs and assertions. Finally, it supports Hardhat's [console.log](https://github.com/brockelmore/forge-std/blob/master/src/console.sol). The logging functionalities require `-vvvv`. - -```solidity -pragma solidity 0.8.10; - -import "forge-std/Test.sol"; - -contract ContractTest is Test { - function testExample() public { - vm.roll(100); - console.log(1); - emit log("hi"); - assertTrue(true); - } -} -``` - -## Development - -This project uses [Foundry](https://getfoundry.sh). See the [book](https://book.getfoundry.sh/getting-started/installation.html) for instructions on how to install and use Foundry. + - Westend Asset Hub address: `5GAdkdRw3LSV27vjqs6rg5xzHNQVUwoR8EfHE7UVGG8s6bYG` diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..b93cf4b --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit b93cf4bc34ff214c099dc970b153f85ade8c9f66 diff --git a/lib/forge-std/.github/workflows/tests.yml b/lib/forge-std/.github/workflows/tests.yml deleted file mode 100644 index d90c17b..0000000 --- a/lib/forge-std/.github/workflows/tests.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Tests -on: [push, pull_request] - -jobs: - check: - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - - - name: Install Foundry - uses: onbjerg/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dependencies - run: forge install - - name: Run tests - run: forge test -vvv diff --git a/lib/forge-std/.gitignore b/lib/forge-std/.gitignore deleted file mode 100644 index d8a1d07..0000000 --- a/lib/forge-std/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -cache/ -out/ diff --git a/lib/forge-std/.gitmodules b/lib/forge-std/.gitmodules deleted file mode 100644 index e124719..0000000 --- a/lib/forge-std/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/ds-test"] - path = lib/ds-test - url = https://github.com/dapphub/ds-test diff --git a/lib/forge-std/LICENSE-APACHE b/lib/forge-std/LICENSE-APACHE deleted file mode 100644 index 8300044..0000000 --- a/lib/forge-std/LICENSE-APACHE +++ /dev/null @@ -1,203 +0,0 @@ -Copyright (c) 2021 Brock Elmore - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/lib/forge-std/LICENSE-MIT b/lib/forge-std/LICENSE-MIT deleted file mode 100644 index 3bbce32..0000000 --- a/lib/forge-std/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2021 Brock Elmore - -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 O THE USE OR OTHER -DEALINGS IN THE SOFTWARE.R diff --git a/lib/forge-std/README.md b/lib/forge-std/README.md deleted file mode 100644 index 381531c..0000000 --- a/lib/forge-std/README.md +++ /dev/null @@ -1,226 +0,0 @@ -# Forge Standard Library • [![tests](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml/badge.svg)](https://github.com/brockelmore/forge-std/actions/workflows/tests.yml) - -Forge Standard Library is a collection of helpful contracts for use with [`forge` and `foundry`](https://github.com/gakonst/foundry). It leverages `forge`'s cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. For more in-depth usage examples checkout the [tests](https://github.com/brockelmore/forge-std/blob/master/src/test). - -## Install - -```bash -forge install foundry-rs/forge-std -``` - -## Contracts -### stdError - -This is a helper contract for errors and reverts. In `forge`, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors. - -See the contract itself for all error codes. - -#### Example usage - -```solidity - -import "forge-std/Test.sol"; - -contract TestContract is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } -} - -contract ErrorsTest { - function arithmeticError(uint256 a) public { - uint256 a = a - 100; - } -} -``` - -### stdStorage - -This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). - -This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. - -I.e.: -```solidity -struct T { - // depth 0 - uint256 a; - // depth 1 - uint256 b; -} -``` - -#### Example usage - -```solidity -import "forge-std/Test.sol"; - -contract TestContract is Test { - using stdStorage for StdStorage; - - Storage test; - - function setUp() public { - test = new Storage(); - } - - function testFindExists() public { - // Lets say we want to find the slot for the public - // variable `exists`. We just pass in the function selector - // to the `find` command - uint256 slot = storage.target(address(test)).sig("exists()").find(); - assertEq(slot, 0); - } - - function testWriteExists() public { - // Lets say we want to write to the slot for the public - // variable `exists`. We just pass in the function selector - // to the `checked_write` command - storage.target(address(test)).sig("exists()").checked_write(100); - assertEq(test.exists(), 100); - } - - // It supports arbitrary storage layouts, like assembly based storage locations - function testFindHidden() public { - // `hidden` is a random hash of a bytes, iteration through slots would - // not find it. Our mechanism does - // Also, you can use the selector instead of a string - uint256 slot = storage.target(address(test)).sig(test.hidden.selector).find(); - assertEq(slot, keccak256("my.random.var")); - } - - // If targeting a mapping, you have to pass in the keys necessary to perform the find - // i.e.: - function testFindMapping() public { - uint256 slot = storage - .target(address(test)) - .sig(test.map_addr.selector) - .with_key(address(this)) - .find(); - // in the `Storage` constructor, we wrote that this address' value was 1 in the map - // so when we load the slot, we expect it to be 1 - assertEq(vm.load(slot), 1); - } - - // If the target is a struct, you can specify the field depth: - function testFindStruct() public { - // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. - uint256 slot_for_a_field = storage - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(0) - .find(); - - uint256 slot_for_b_field = storage - .target(address(test)) - .sig(test.basicStruct.selector) - .depth(1) - .find(); - - assertEq(vm.load(slot_for_a_field), 1); - assertEq(vm.load(slot_for_b_field), 2); - } -} - -// A complex storage contract -contract Storage { - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - constructor() { - map_addr[msg.sender] = 1; - } - - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(address => Packed) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basicStruct = UnpackedStruct({ - a: 1, - b: 2, - }); - - function hidden() public returns (bytes32 t) { - // an extremely hidden storage slot - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } -} -``` - -### stdCheats - -This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. - - -#### Example usage: -```solidity - -// SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; - -// Inherit the stdCheats -contract StdCheatsTest is Test { - Bar test; - function setUp() public { - test = new Bar(); - } - - function testHoax() public { - // we call `hoax`, which gives the target address - // eth and then calls `prank` - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - - // overloaded to allow you to specify how much eth to - // initialize the address with - hoax(address(1337), 1); - test.bar{value: 1}(address(1337)); - } - - function testStartHoax() public { - // we call `startHoax`, which gives the target address - // eth and then calls `startPrank` - // - // it is also overloaded so that you can specify an eth amount - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } -} - -contract Bar { - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } -} -``` - -### `console.log` - -Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log): -```solidity -// import it indirectly via Test.sol -import "forge-std/Test.sol"; -// or directly import it -import "forge-std/console.sol"; -... -console.log(someValue); -``` diff --git a/lib/forge-std/lib/ds-test/.gitignore b/lib/forge-std/lib/ds-test/.gitignore deleted file mode 100644 index 63f0b2c..0000000 --- a/lib/forge-std/lib/ds-test/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/.dapple -/build -/out diff --git a/lib/forge-std/lib/ds-test/LICENSE b/lib/forge-std/lib/ds-test/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/lib/forge-std/lib/ds-test/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/lib/forge-std/lib/ds-test/Makefile b/lib/forge-std/lib/ds-test/Makefile deleted file mode 100644 index 661dac4..0000000 --- a/lib/forge-std/lib/ds-test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -all:; dapp build - -test: - -dapp --use solc:0.4.23 build - -dapp --use solc:0.4.26 build - -dapp --use solc:0.5.17 build - -dapp --use solc:0.6.12 build - -dapp --use solc:0.7.5 build - -demo: - DAPP_SRC=demo dapp --use solc:0.7.5 build - -hevm dapp-test --verbose 3 - -.PHONY: test demo diff --git a/lib/forge-std/lib/ds-test/default.nix b/lib/forge-std/lib/ds-test/default.nix deleted file mode 100644 index cf65419..0000000 --- a/lib/forge-std/lib/ds-test/default.nix +++ /dev/null @@ -1,4 +0,0 @@ -{ solidityPackage, dappsys }: solidityPackage { - name = "ds-test"; - src = ./src; -} diff --git a/lib/forge-std/lib/ds-test/demo/demo.sol b/lib/forge-std/lib/ds-test/demo/demo.sol deleted file mode 100644 index d3a7d81..0000000 --- a/lib/forge-std/lib/ds-test/demo/demo.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity >=0.4.23; - -import "../src/test.sol"; - -contract DemoTest is DSTest { - function test_this() public pure { - require(true); - } - function test_logs() public { - emit log("-- log(string)"); - emit log("a string"); - - emit log("-- log_named_uint(string, uint)"); - log_named_uint("uint", 512); - - emit log("-- log_named_int(string, int)"); - log_named_int("int", -512); - - emit log("-- log_named_address(string, address)"); - log_named_address("address", address(this)); - - emit log("-- log_named_bytes32(string, bytes32)"); - log_named_bytes32("bytes32", "a string"); - - emit log("-- log_named_bytes(string, bytes)"); - log_named_bytes("bytes", hex"cafefe"); - - emit log("-- log_named_string(string, string)"); - log_named_string("string", "a string"); - - emit log("-- log_named_decimal_uint(string, uint, uint)"); - log_named_decimal_uint("decimal uint", 1.0e18, 18); - - emit log("-- log_named_decimal_int(string, int, uint)"); - log_named_decimal_int("decimal int", -1.0e18, 18); - } - event log_old_named_uint(bytes32,uint); - function test_old_logs() public { - log_old_named_uint("key", 500); - log_named_bytes32("bkey", "val"); - } - function test_trace() public view { - this.echo("string 1", "string 2"); - } - function test_multiline() public { - emit log("a multiline\\n" "string"); - emit log("a multiline " "string"); - log_bytes("a string"); - log_bytes("a multiline\n" "string"); - log_bytes("a multiline\\n" "string"); - emit log(unicode"Ώ"); - logs(hex"0000"); - log_named_bytes("0x0000", hex"0000"); - logs(hex"ff"); - } - function echo(string memory s1, string memory s2) public pure - returns (string memory, string memory) - { - return (s1, s2); - } - - function prove_this(uint x) public { - log_named_uint("sym x", x); - assertGt(x + 1, 0); - } - - function test_logn() public { - assembly { - log0(0x01, 0x02) - log1(0x01, 0x02, 0x03) - log2(0x01, 0x02, 0x03, 0x04) - log3(0x01, 0x02, 0x03, 0x04, 0x05) - } - } - - event MyEvent(uint, uint indexed, uint, uint indexed); - function test_events() public { - emit MyEvent(1, 2, 3, 4); - } - - function test_asserts() public { - string memory err = "this test has failed!"; - emit log("## assertTrue(bool)\n"); - assertTrue(false); - emit log("\n"); - assertTrue(false, err); - - emit log("\n## assertEq(address,address)\n"); - assertEq(address(this), msg.sender); - emit log("\n"); - assertEq(address(this), msg.sender, err); - - emit log("\n## assertEq32(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(bytes32,bytes32)\n"); - assertEq32("bytes 1", "bytes 2"); - emit log("\n"); - assertEq32("bytes 1", "bytes 2", err); - - emit log("\n## assertEq(uint,uint)\n"); - assertEq(uint(0), 1); - emit log("\n"); - assertEq(uint(0), 1, err); - - emit log("\n## assertEq(int,int)\n"); - assertEq(-1, -2); - emit log("\n"); - assertEq(-1, -2, err); - - emit log("\n## assertEqDecimal(int,int,uint)\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertEqDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertEqDecimal(uint,uint,uint)\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGt(uint,uint)\n"); - assertGt(uint(0), 0); - emit log("\n"); - assertGt(uint(0), 0, err); - - emit log("\n## assertGt(int,int)\n"); - assertGt(-1, -1); - emit log("\n"); - assertGt(-1, -1, err); - - emit log("\n## assertGtDecimal(int,int,uint)\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGtDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGtDecimal(uint,uint,uint)\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertGe(uint,uint)\n"); - assertGe(uint(0), 1); - emit log("\n"); - assertGe(uint(0), 1, err); - - emit log("\n## assertGe(int,int)\n"); - assertGe(-1, 0); - emit log("\n"); - assertGe(-1, 0, err); - - emit log("\n## assertGeDecimal(int,int,uint)\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18); - emit log("\n"); - assertGeDecimal(-2.0e18, -1.1e18, 18, err); - - emit log("\n## assertGeDecimal(uint,uint,uint)\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18); - emit log("\n"); - assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); - - emit log("\n## assertLt(uint,uint)\n"); - assertLt(uint(0), 0); - emit log("\n"); - assertLt(uint(0), 0, err); - - emit log("\n## assertLt(int,int)\n"); - assertLt(-1, -1); - emit log("\n"); - assertLt(-1, -1, err); - - emit log("\n## assertLtDecimal(int,int,uint)\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLtDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLtDecimal(uint,uint,uint)\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertLe(uint,uint)\n"); - assertLe(uint(1), 0); - emit log("\n"); - assertLe(uint(1), 0, err); - - emit log("\n## assertLe(int,int)\n"); - assertLe(0, -1); - emit log("\n"); - assertLe(0, -1, err); - - emit log("\n## assertLeDecimal(int,int,uint)\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18); - emit log("\n"); - assertLeDecimal(-1.0e18, -1.1e18, 18, err); - - emit log("\n## assertLeDecimal(uint,uint,uint)\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18); - emit log("\n"); - assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); - - emit log("\n## assertEq(string,string)\n"); - string memory s1 = "string 1"; - string memory s2 = "string 2"; - assertEq(s1, s2); - emit log("\n"); - assertEq(s1, s2, err); - - emit log("\n## assertEq0(bytes,bytes)\n"); - assertEq0(hex"abcdef01", hex"abcdef02"); - log("\n"); - assertEq0(hex"abcdef01", hex"abcdef02", err); - } -} - -contract DemoTestWithSetUp { - function setUp() public { - } - function test_pass() public pure { - } -} diff --git a/lib/forge-std/lib/ds-test/src/test.sol b/lib/forge-std/lib/ds-test/src/test.sol deleted file mode 100644 index 940c466..0000000 --- a/lib/forge-std/lib/ds-test/src/test.sol +++ /dev/null @@ -1,469 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -pragma solidity >=0.5.0; - -contract DSTest { - event log (string); - event logs (bytes); - - event log_address (address); - event log_bytes32 (bytes32); - event log_int (int); - event log_uint (uint); - event log_bytes (bytes); - event log_string (string); - - event log_named_address (string key, address val); - event log_named_bytes32 (string key, bytes32 val); - event log_named_decimal_int (string key, int val, uint decimals); - event log_named_decimal_uint (string key, uint val, uint decimals); - event log_named_int (string key, int val); - event log_named_uint (string key, uint val); - event log_named_bytes (string key, bytes val); - event log_named_string (string key, string val); - - bool public IS_TEST = true; - bool private _failed; - - address constant HEVM_ADDRESS = - address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); - - modifier mayRevert() { _; } - modifier testopts(string memory) { _; } - - function failed() public returns (bool) { - if (_failed) { - return _failed; - } else { - bool globalFailed = false; - if (hasHEVMContext()) { - (, bytes memory retdata) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("load(address,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed")) - ) - ); - globalFailed = abi.decode(retdata, (bool)); - } - return globalFailed; - } - } - - function fail() internal { - if (hasHEVMContext()) { - (bool status, ) = HEVM_ADDRESS.call( - abi.encodePacked( - bytes4(keccak256("store(address,bytes32,bytes32)")), - abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) - ) - ); - status; // Silence compiler warnings - } - _failed = true; - } - - function hasHEVMContext() internal view returns (bool) { - uint256 hevmCodeSize = 0; - assembly { - hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) - } - return hevmCodeSize > 0; - } - - modifier logs_gas() { - uint startGas = gasleft(); - _; - uint endGas = gasleft(); - emit log_named_uint("gas", startGas - endGas); - } - - function assertTrue(bool condition) internal { - if (!condition) { - emit log("Error: Assertion Failed"); - fail(); - } - } - - function assertTrue(bool condition, string memory err) internal { - if (!condition) { - emit log_named_string("Error", err); - assertTrue(condition); - } - } - - function assertEq(address a, address b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [address]"); - emit log_named_address(" Expected", b); - emit log_named_address(" Actual", a); - fail(); - } - } - function assertEq(address a, address b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - - function assertEq(bytes32 a, bytes32 b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [bytes32]"); - emit log_named_bytes32(" Expected", b); - emit log_named_bytes32(" Actual", a); - fail(); - } - } - function assertEq(bytes32 a, bytes32 b, string memory err) internal { - if (a != b) { - emit log_named_string ("Error", err); - assertEq(a, b); - } - } - function assertEq32(bytes32 a, bytes32 b) internal { - assertEq(a, b); - } - function assertEq32(bytes32 a, bytes32 b, string memory err) internal { - assertEq(a, b, err); - } - - function assertEq(int a, int b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [int]"); - emit log_named_int(" Expected", b); - emit log_named_int(" Actual", a); - fail(); - } - } - function assertEq(int a, int b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEq(uint a, uint b) internal { - if (a != b) { - emit log("Error: a == b not satisfied [uint]"); - emit log_named_uint(" Expected", b); - emit log_named_uint(" Actual", a); - fail(); - } - } - function assertEq(uint a, uint b, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - function assertEqDecimal(int a, int b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal int]"); - emit log_named_decimal_int(" Expected", b, decimals); - emit log_named_decimal_int(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - function assertEqDecimal(uint a, uint b, uint decimals) internal { - if (a != b) { - emit log("Error: a == b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Expected", b, decimals); - emit log_named_decimal_uint(" Actual", a, decimals); - fail(); - } - } - function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a != b) { - emit log_named_string("Error", err); - assertEqDecimal(a, b, decimals); - } - } - - function assertGt(uint a, uint b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGt(uint a, uint b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGt(int a, int b) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGt(int a, int b, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGt(a, b); - } - } - function assertGtDecimal(int a, int b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - function assertGtDecimal(uint a, uint b, uint decimals) internal { - if (a <= b) { - emit log("Error: a > b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a <= b) { - emit log_named_string("Error", err); - assertGtDecimal(a, b, decimals); - } - } - - function assertGe(uint a, uint b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertGe(uint a, uint b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGe(int a, int b) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertGe(int a, int b, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGe(a, b); - } - } - function assertGeDecimal(int a, int b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - function assertGeDecimal(uint a, uint b, uint decimals) internal { - if (a < b) { - emit log("Error: a >= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a < b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertLt(uint a, uint b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLt(uint a, uint b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLt(int a, int b) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLt(int a, int b, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLt(a, b); - } - } - function assertLtDecimal(int a, int b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - function assertLtDecimal(uint a, uint b, uint decimals) internal { - if (a >= b) { - emit log("Error: a < b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a >= b) { - emit log_named_string("Error", err); - assertLtDecimal(a, b, decimals); - } - } - - function assertLe(uint a, uint b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [uint]"); - emit log_named_uint(" Value a", a); - emit log_named_uint(" Value b", b); - fail(); - } - } - function assertLe(uint a, uint b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLe(int a, int b) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [int]"); - emit log_named_int(" Value a", a); - emit log_named_int(" Value b", b); - fail(); - } - } - function assertLe(int a, int b, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLe(a, b); - } - } - function assertLeDecimal(int a, int b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal int]"); - emit log_named_decimal_int(" Value a", a, decimals); - emit log_named_decimal_int(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertLeDecimal(a, b, decimals); - } - } - function assertLeDecimal(uint a, uint b, uint decimals) internal { - if (a > b) { - emit log("Error: a <= b not satisfied [decimal uint]"); - emit log_named_decimal_uint(" Value a", a, decimals); - emit log_named_decimal_uint(" Value b", b, decimals); - fail(); - } - } - function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { - if (a > b) { - emit log_named_string("Error", err); - assertGeDecimal(a, b, decimals); - } - } - - function assertEq(string memory a, string memory b) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log("Error: a == b not satisfied [string]"); - emit log_named_string(" Value a", a); - emit log_named_string(" Value b", b); - fail(); - } - } - function assertEq(string memory a, string memory b, string memory err) internal { - if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { - emit log_named_string("Error", err); - assertEq(a, b); - } - } - - function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { - ok = true; - if (a.length == b.length) { - for (uint i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - ok = false; - } - } - } else { - ok = false; - } - } - function assertEq0(bytes memory a, bytes memory b) internal { - if (!checkEq0(a, b)) { - emit log("Error: a == b not satisfied [bytes]"); - emit log_named_bytes(" Expected", a); - emit log_named_bytes(" Actual", b); - fail(); - } - } - function assertEq0(bytes memory a, bytes memory b, string memory err) internal { - if (!checkEq0(a, b)) { - emit log_named_string("Error", err); - assertEq0(a, b); - } - } -} diff --git a/lib/forge-std/src/Test.sol b/lib/forge-std/src/Test.sol deleted file mode 100644 index 8d189b7..0000000 --- a/lib/forge-std/src/Test.sol +++ /dev/null @@ -1,371 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity >=0.6.0 <0.9.0; - -import "./Vm.sol"; -import "ds-test/test.sol"; -import "./console.sol"; - -// Wrappers around Cheatcodes to avoid footguns -abstract contract Test is DSTest { - using stdStorage for StdStorage; - - event WARNING_Deprecated(string msg); - - Vm public constant vm = Vm(HEVM_ADDRESS); - StdStorage internal stdstore; - - // Skip forward or rewind time by the specified number of seconds - function skip(uint256 time) public { - vm.warp(block.timestamp + time); - } - - function rewind(uint256 time) public { - vm.warp(block.timestamp - time); - } - - // Setup a prank from an address that has some ether - function hoax(address who) public { - vm.deal(who, 1 << 128); - vm.prank(who); - } - - function hoax(address who, uint256 give) public { - vm.deal(who, give); - vm.prank(who); - } - - function hoax(address who, address origin) public { - vm.deal(who, 1 << 128); - vm.prank(who, origin); - } - - function hoax(address who, address origin, uint256 give) public { - vm.deal(who, give); - vm.prank(who, origin); - } - - // Start perpetual prank from an address that has some ether - function startHoax(address who) public { - vm.deal(who, 1 << 128); - vm.startPrank(who); - } - - function startHoax(address who, uint256 give) public { - vm.deal(who, give); - vm.startPrank(who); - } - - // Start perpetual prank from an address that has some ether - // tx.origin is set to the origin parameter - function startHoax(address who, address origin) public { - vm.deal(who, 1 << 128); - vm.startPrank(who, origin); - } - - function startHoax(address who, address origin, uint256 give) public { - vm.deal(who, give); - vm.startPrank(who, origin); - } - - // DEPRECATED: Use `deal` instead - function tip(address token, address to, uint256 give) public { - emit WARNING_Deprecated("The `tip` stdcheat has been deprecated. Use `deal` instead."); - stdstore - .target(token) - .sig(0x70a08231) - .with_key(to) - .checked_write(give); - } - - // The same as Hevm's `deal` - // Use the alternative signature for ERC20 tokens - function deal(address to, uint256 give) public { - vm.deal(to, give); - } - - // Set the balance of an account for any ERC20 token - // Use the alternative signature to update `totalSupply` - function deal(address token, address to, uint256 give) public { - deal(token, to, give, false); - } - - function deal(address token, address to, uint256 give, bool adjust) public { - // get current balance - (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to)); - uint256 prevBal = abi.decode(balData, (uint256)); - - // update balance - stdstore - .target(token) - .sig(0x70a08231) - .with_key(to) - .checked_write(give); - - // update total supply - if(adjust){ - (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd)); - uint256 totSup = abi.decode(totSupData, (uint256)); - if(give < prevBal) { - totSup -= (prevBal - give); - } else { - totSup += (give - prevBal); - } - stdstore - .target(token) - .sig(0x18160ddd) - .checked_write(totSup); - } - } - - // Deploy a contract by fetching the contract bytecode from - // the artifacts directory - // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` - function deployCode(string memory what, bytes memory args) - public - returns (address addr) - { - bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - } - - function deployCode(string memory what) - public - returns (address addr) - { - bytes memory bytecode = vm.getCode(what); - assembly { - addr := create(0, add(bytecode, 0x20), mload(bytecode)) - } - } -} - - -library stdError { - bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); - bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); - bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); - bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); - bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); - bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); - bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); - bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); - bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); - // DEPRECATED: Use Hevm's `expectRevert` without any arguments instead - bytes public constant lowLevelError = bytes(""); // `0x` -} - -struct StdStorage { - mapping (address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; - mapping (address => mapping(bytes4 => mapping(bytes32 => bool))) finds; - - bytes32[] _keys; - bytes4 _sig; - uint256 _depth; - address _target; - bytes32 _set; -} - - -library stdStorage { - event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint slot); - event WARNING_UninitedSlot(address who, uint slot); - - Vm private constant vm_std_store = Vm(address(uint160(uint256(keccak256('hevm cheat code'))))); - - function sigs( - string memory sigStr - ) - internal - pure - returns (bytes4) - { - return bytes4(keccak256(bytes(sigStr))); - } - - /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against - // slot complexity: - // if flat, will be bytes32(uint256(uint)); - // if map, will be keccak256(abi.encode(key, uint(slot))); - // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); - // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); - function find( - StdStorage storage self - ) - internal - returns (uint256) - { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - // calldata to test against - if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - vm_std_store.record(); - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32*field_depth); - } - - (bytes32[] memory reads, ) = vm_std_store.accesses(address(who)); - if (reads.length == 1) { - bytes32 curr = vm_std_store.load(who, reads[0]); - if (curr == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[0])); - } - if (fdat != curr) { - require(false, "Packed slot. This would cause dangerous overwriting and currently isnt supported"); - } - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - } else if (reads.length > 1) { - for (uint256 i = 0; i < reads.length; i++) { - bytes32 prev = vm_std_store.load(who, reads[i]); - if (prev == bytes32(0)) { - emit WARNING_UninitedSlot(who, uint256(reads[i])); - } - // store - vm_std_store.store(who, reads[i], bytes32(hex"1337")); - bool success; - bytes memory rdat; - { - (success, rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32*field_depth); - } - - if (success && fdat == bytes32(hex"1337")) { - // we found which of the slots is the actual one - emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); - self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); - self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; - vm_std_store.store(who, reads[i], prev); - break; - } - vm_std_store.store(who, reads[i], prev); - } - } else { - require(false, "No storage use detected for target"); - } - - require(self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], "NotFound"); - - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - - return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; - } - - function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { - self._target = _target; - return self; - } - - function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { - self._sig = _sig; - return self; - } - - function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { - self._sig = sigs(_sig); - return self; - } - - function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { - self._keys.push(bytes32(uint256(uint160(who)))); - return self; - } - - function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { - self._keys.push(bytes32(amt)); - return self; - } - function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { - self._keys.push(key); - return self; - } - - function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { - self._depth = _depth; - return self; - } - - function checked_write(StdStorage storage self, address who) internal { - checked_write(self, bytes32(uint256(uint160(who)))); - } - - function checked_write(StdStorage storage self, uint256 amt) internal { - checked_write(self, bytes32(amt)); - } - - function checked_write(StdStorage storage self, bool write) internal { - bytes32 t; - assembly { - t := write - } - checked_write(self, t); - } - - function checked_write( - StdStorage storage self, - bytes32 set - ) internal { - address who = self._target; - bytes4 fsig = self._sig; - uint256 field_depth = self._depth; - bytes32[] memory ins = self._keys; - - bytes memory cald = abi.encodePacked(fsig, flatten(ins)); - if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { - find(self); - } - bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); - - bytes32 fdat; - { - (, bytes memory rdat) = who.staticcall(cald); - fdat = bytesToBytes32(rdat, 32*field_depth); - } - bytes32 curr = vm_std_store.load(who, slot); - - if (fdat != curr) { - require(false, "Packed slot. This would cause dangerous overwriting and currently isnt supported"); - } - vm_std_store.store(who, slot, set); - delete self._target; - delete self._sig; - delete self._keys; - delete self._depth; - } - - function bytesToBytes32(bytes memory b, uint offset) public pure returns (bytes32) { - bytes32 out; - - uint256 max = b.length > 32 ? 32 : b.length; - for (uint i = 0; i < max; i++) { - out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); - } - return out; - } - - function flatten(bytes32[] memory b) private pure returns (bytes memory) - { - bytes memory result = new bytes(b.length * 32); - for (uint256 i = 0; i < b.length; i++) { - bytes32 k = b[i]; - assembly { - mstore(add(result, add(32, mul(32, i))), k) - } - } - - return result; - } -} diff --git a/lib/forge-std/src/Vm.sol b/lib/forge-std/src/Vm.sol deleted file mode 100644 index ca6680e..0000000 --- a/lib/forge-std/src/Vm.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity >=0.6.0; -pragma experimental ABIEncoderV2; - -interface Vm { - // Set block.timestamp (newTimestamp) - function warp(uint256) external; - // Set block.height (newHeight) - function roll(uint256) external; - // Set block.basefee (newBasefee) - function fee(uint256) external; - // Loads a storage slot from an address (who, slot) - function load(address,bytes32) external returns (bytes32); - // Stores a value to an address' storage slot, (who, slot, value) - function store(address,bytes32,bytes32) external; - // Signs data, (privateKey, digest) => (v, r, s) - function sign(uint256,bytes32) external returns (uint8,bytes32,bytes32); - // Gets address for a given private key, (privateKey) => (address) - function addr(uint256) external returns (address); - // Performs a foreign function call via terminal, (stringInputs) => (result) - function ffi(string[] calldata) external returns (bytes memory); - // Sets the *next* call's msg.sender to be the input address - function prank(address) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called - function startPrank(address) external; - // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input - function prank(address,address) external; - // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input - function startPrank(address,address) external; - // Resets subsequent calls' msg.sender to be `address(this)` - function stopPrank() external; - // Sets an address' balance, (who, newBalance) - function deal(address, uint256) external; - // Sets an address' code, (who, newCode) - function etch(address, bytes calldata) external; - // Expects an error on next call - function expectRevert(bytes calldata) external; - function expectRevert(bytes4) external; - function expectRevert() external; - // Record all storage reads and writes - function record() external; - // Gets all accessed reads and write slot from a recording session, for a given address - function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes); - // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). - // Call this function, then emit an event, then call a function. Internally after the call, we check if - // logs were emitted in the expected order with the expected topics and data (as specified by the booleans) - function expectEmit(bool,bool,bool,bool) external; - // Mocks a call to an address, returning specified data. - // Calldata can either be strict or a partial match, e.g. if you only - // pass a Solidity selector to the expected calldata, then the entire Solidity - // function will be mocked. - function mockCall(address,bytes calldata,bytes calldata) external; - // Clears all mocked calls - function clearMockedCalls() external; - // Expect a call to an address with the specified calldata. - // Calldata can either be strict or a partial match - function expectCall(address,bytes calldata) external; - // Gets the code from an artifact file. Takes in the relative path to the json file - function getCode(string calldata) external returns (bytes memory); - // Labels an address in call traces - function label(address, string calldata) external; - // If the condition is false, discard this run's fuzz inputs and generate new ones - function assume(bool) external; -} diff --git a/lib/forge-std/src/console.sol b/lib/forge-std/src/console.sol deleted file mode 100644 index 6f28592..0000000 --- a/lib/forge-std/src/console.sol +++ /dev/null @@ -1,1532 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.4.22 <0.9.0; - -library console { - address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); - - function _sendLogPayload(bytes memory payload) private view { - uint256 payloadLength = payload.length; - address consoleAddress = CONSOLE_ADDRESS; - assembly { - let payloadStart := add(payload, 32) - let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) - } - } - - function log() internal view { - _sendLogPayload(abi.encodeWithSignature("log()")); - } - - function logInt(int p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); - } - - function logUint(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function logString(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function logBool(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function logAddress(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function logBytes(bytes memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); - } - - function logBytes1(bytes1 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); - } - - function logBytes2(bytes2 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); - } - - function logBytes3(bytes3 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); - } - - function logBytes4(bytes4 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); - } - - function logBytes5(bytes5 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); - } - - function logBytes6(bytes6 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); - } - - function logBytes7(bytes7 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); - } - - function logBytes8(bytes8 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); - } - - function logBytes9(bytes9 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); - } - - function logBytes10(bytes10 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); - } - - function logBytes11(bytes11 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); - } - - function logBytes12(bytes12 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); - } - - function logBytes13(bytes13 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); - } - - function logBytes14(bytes14 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); - } - - function logBytes15(bytes15 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); - } - - function logBytes16(bytes16 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); - } - - function logBytes17(bytes17 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); - } - - function logBytes18(bytes18 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); - } - - function logBytes19(bytes19 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); - } - - function logBytes20(bytes20 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); - } - - function logBytes21(bytes21 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); - } - - function logBytes22(bytes22 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); - } - - function logBytes23(bytes23 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); - } - - function logBytes24(bytes24 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); - } - - function logBytes25(bytes25 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); - } - - function logBytes26(bytes26 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); - } - - function logBytes27(bytes27 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); - } - - function logBytes28(bytes28 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); - } - - function logBytes29(bytes29 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); - } - - function logBytes30(bytes30 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); - } - - function logBytes31(bytes31 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); - } - - function logBytes32(bytes32 p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); - } - - function log(uint p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); - } - - function log(string memory p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); - } - - function log(bool p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); - } - - function log(address p0) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); - } - - function log(uint p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); - } - - function log(uint p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); - } - - function log(uint p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); - } - - function log(uint p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); - } - - function log(string memory p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); - } - - function log(string memory p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); - } - - function log(string memory p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); - } - - function log(string memory p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); - } - - function log(bool p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); - } - - function log(bool p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); - } - - function log(bool p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); - } - - function log(bool p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); - } - - function log(address p0, uint p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); - } - - function log(address p0, string memory p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); - } - - function log(address p0, bool p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); - } - - function log(address p0, address p1) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); - } - - function log(uint p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); - } - - function log(uint p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); - } - - function log(uint p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); - } - - function log(uint p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); - } - - function log(uint p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); - } - - function log(uint p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); - } - - function log(uint p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); - } - - function log(uint p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); - } - - function log(uint p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); - } - - function log(uint p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); - } - - function log(uint p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); - } - - function log(uint p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); - } - - function log(uint p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); - } - - function log(string memory p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); - } - - function log(string memory p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); - } - - function log(string memory p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); - } - - function log(string memory p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); - } - - function log(string memory p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); - } - - function log(string memory p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); - } - - function log(string memory p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); - } - - function log(bool p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); - } - - function log(bool p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); - } - - function log(bool p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); - } - - function log(bool p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); - } - - function log(bool p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); - } - - function log(bool p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); - } - - function log(bool p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); - } - - function log(bool p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); - } - - function log(bool p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); - } - - function log(bool p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); - } - - function log(bool p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); - } - - function log(bool p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); - } - - function log(bool p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); - } - - function log(address p0, uint p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); - } - - function log(address p0, uint p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); - } - - function log(address p0, uint p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); - } - - function log(address p0, uint p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); - } - - function log(address p0, string memory p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); - } - - function log(address p0, string memory p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); - } - - function log(address p0, string memory p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); - } - - function log(address p0, string memory p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); - } - - function log(address p0, bool p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); - } - - function log(address p0, bool p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); - } - - function log(address p0, bool p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); - } - - function log(address p0, bool p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); - } - - function log(address p0, address p1, uint p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); - } - - function log(address p0, address p1, string memory p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); - } - - function log(address p0, address p1, bool p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); - } - - function log(address p0, address p1, address p2) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); - } - - function log(uint p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); - } - - function log(uint p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); - } - - function log(string memory p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); - } - - function log(bool p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, uint p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, string memory p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, bool p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, uint p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, string memory p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, bool p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, uint p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, string memory p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, bool p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); - } - - function log(address p0, address p1, address p2, address p3) internal view { - _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); - } - -} \ No newline at end of file diff --git a/lib/forge-std/src/test/StdCheats.t.sol b/lib/forge-std/src/test/StdCheats.t.sol deleted file mode 100644 index 6de3744..0000000 --- a/lib/forge-std/src/test/StdCheats.t.sol +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity >=0.6.0 <0.9.0; - -import "../Test.sol"; - -contract StdCheatsTest is Test { - Bar test; - - function setUp() public { - test = new Bar(); - } - - function testSkip() public { - vm.warp(100); - skip(25); - assertEq(block.timestamp, 125); - } - - function testRewind() public { - vm.warp(100); - rewind(25); - assertEq(block.timestamp, 75); - } - - function testHoax() public { - hoax(address(1337)); - test.bar{value: 100}(address(1337)); - } - - function testHoaxOrigin() public { - hoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - } - - function testHoaxDifferentAddresses() public { - hoax(address(1337), address(7331)); - test.origin{value: 100}(address(1337), address(7331)); - } - - function testStartHoax() public { - startHoax(address(1337)); - test.bar{value: 100}(address(1337)); - test.bar{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testStartHoaxOrigin() public { - startHoax(address(1337), address(1337)); - test.origin{value: 100}(address(1337)); - test.origin{value: 100}(address(1337)); - vm.stopPrank(); - test.bar(address(this)); - } - - function testDeal() public { - deal(address(this), 1 ether); - assertEq(address(this).balance, 1 ether); - } - - function testDealToken() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18); - assertEq(barToken.balanceOf(address(this)), 10000e18); - } - - function testDealTokenAdjustTS() public { - Bar barToken = new Bar(); - address bar = address(barToken); - deal(bar, address(this), 10000e18, true); - assertEq(barToken.balanceOf(address(this)), 10000e18); - assertEq(barToken.totalSupply(), 20000e18); - deal(bar, address(this), 0, true); - assertEq(barToken.balanceOf(address(this)), 0); - assertEq(barToken.totalSupply(), 10000e18); - } - - function testDeployCode() public { - address deployed = deployCode("StdCheats.t.sol:StdCheatsTest", bytes("")); - assertEq(string(getCode(deployed)), string(getCode(address(this)))); - } - - function testDeployCodeNoArgs() public { - address deployed = deployCode("StdCheats.t.sol:StdCheatsTest"); - assertEq(string(getCode(deployed)), string(getCode(address(this)))); - } - - function getCode(address who) internal view returns (bytes memory o_code) { - assembly { - // retrieve the size of the code, this needs assembly - let size := extcodesize(who) - // allocate output byte array - this could also be done without assembly - // by using o_code = new bytes(size) - o_code := mload(0x40) - // new "memory end" including padding - mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) - // store length in memory - mstore(o_code, size) - // actually retrieve the code, this needs assembly - extcodecopy(who, add(o_code, 0x20), 0, size) - } - } -} - -contract Bar { - constructor() { - /// `DEAL` STDCHEAT - totalSupply = 10000e18; - balanceOf[address(this)] = totalSupply; - } - - /// `HOAX` STDCHEATS - function bar(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - } - function origin(address expectedSender) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedSender, "!prank"); - } - function origin(address expectedSender, address expectedOrigin) public payable { - require(msg.sender == expectedSender, "!prank"); - require(tx.origin == expectedOrigin, "!prank"); - } - - /// `DEAL` STDCHEAT - mapping (address => uint256) public balanceOf; - uint256 public totalSupply; -} diff --git a/lib/forge-std/src/test/StdError.t.sol b/lib/forge-std/src/test/StdError.t.sol deleted file mode 100644 index 6d93f06..0000000 --- a/lib/forge-std/src/test/StdError.t.sol +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity 0.8.10; - -import "../Test.sol"; - -contract StdErrorsTest is Test { - ErrorsTest test; - - function setUp() public { - test = new ErrorsTest(); - } - - function testExpectAssertion() public { - vm.expectRevert(stdError.assertionError); - test.assertionError(); - } - - function testExpectArithmetic() public { - vm.expectRevert(stdError.arithmeticError); - test.arithmeticError(10); - } - - function testExpectDiv() public { - vm.expectRevert(stdError.divisionError); - test.divError(0); - } - - function testExpectMod() public { - vm.expectRevert(stdError.divisionError); - test.modError(0); - } - - function testExpectEnum() public { - vm.expectRevert(stdError.enumConversionError); - test.enumConversion(1); - } - - function testExpectEncodeStg() public { - vm.expectRevert(stdError.encodeStorageError); - test.encodeStgError(); - } - - function testExpectPop() public { - vm.expectRevert(stdError.popError); - test.pop(); - } - - function testExpectOOB() public { - vm.expectRevert(stdError.indexOOBError); - test.indexOOBError(1); - } - - function testExpectMem() public { - vm.expectRevert(stdError.memOverflowError); - test.mem(); - } - - function testExpectIntern() public { - vm.expectRevert(stdError.zeroVarError); - test.intern(); - } - - function testExpectLowLvl() public { - vm.expectRevert(stdError.lowLevelError); - test.someArr(0); - } -} - -contract ErrorsTest { - enum T { - T1 - } - - uint256[] public someArr; - bytes someBytes; - - function assertionError() public pure { - assert(false); - } - - function arithmeticError(uint256 a) public pure { - a -= 100; - } - - function divError(uint256 a) public pure { - 100 / a; - } - - function modError(uint256 a) public pure { - 100 % a; - } - - function enumConversion(uint256 a) public pure { - T(a); - } - - function encodeStgError() public { - assembly { - sstore(someBytes.slot, 1) - } - keccak256(someBytes); - } - - function pop() public { - someArr.pop(); - } - - function indexOOBError(uint256 a) public pure { - uint256[] memory t = new uint256[](0); - t[a]; - } - - function mem() public pure { - uint256 l = 2**256 / 32; - new uint256[](l); - } - - function intern() public returns (uint256) { - function(uint256) internal returns (uint256) x; - x(2); - return 7; - } -} diff --git a/lib/forge-std/src/test/StdStorage.t.sol b/lib/forge-std/src/test/StdStorage.t.sol deleted file mode 100644 index fe7200b..0000000 --- a/lib/forge-std/src/test/StdStorage.t.sol +++ /dev/null @@ -1,276 +0,0 @@ -// SPDX-License-Identifier: Unlicense -pragma solidity >=0.6.0 <0.9.0; - -import "../Test.sol"; - -contract StdStorageTest is Test { - using stdStorage for StdStorage; - - StorageTest test; - - function setUp() public { - test = new StorageTest(); - } - - function testStorageHidden() public { - assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); - } - - function testStorageObvious() public { - assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); - } - - function testStorageCheckedWriteHidden() public { - stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); - assertEq(uint256(test.hidden()), 100); - } - - function testStorageCheckedWriteObvious() public { - stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); - assertEq(test.exists(), 100); - } - - function testStorageMapStructA() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.map_struct.selector) - .with_key(address(this)) - .depth(0) - .find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); - } - - function testStorageMapStructB() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.map_struct.selector) - .with_key(address(this)) - .depth(1) - .find(); - assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); - } - - function testStorageDeepMap() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.deep_map.selector) - .with_key(address(this)) - .with_key(address(this)) - .find(); - assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint(5)))))), slot); - } - - function testStorageCheckedWriteDeepMap() public { - stdstore - .target(address(test)) - .sig(test.deep_map.selector) - .with_key(address(this)) - .with_key(address(this)) - .checked_write(100); - assertEq(100, test.deep_map(address(this), address(this))); - } - - function testStorageDeepMapStructA() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.deep_map_struct.selector) - .with_key(address(this)) - .with_key(address(this)) - .depth(0) - .find(); - assertEq(bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint(6)))))) + 0), bytes32(slot)); - } - - function testStorageDeepMapStructB() public { - uint256 slot = stdstore - .target(address(test)) - .sig(test.deep_map_struct.selector) - .with_key(address(this)) - .with_key(address(this)) - .depth(1) - .find(); - assertEq(bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint(6)))))) + 1), bytes32(slot)); - } - - function testStorageCheckedWriteDeepMapStructA() public { - stdstore - .target(address(test)) - .sig(test.deep_map_struct.selector) - .with_key(address(this)) - .with_key(address(this)) - .depth(0) - .checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(100, a); - assertEq(0, b); - } - - function testStorageCheckedWriteDeepMapStructB() public { - stdstore - .target(address(test)) - .sig(test.deep_map_struct.selector) - .with_key(address(this)) - .with_key(address(this)) - .depth(1) - .checked_write(100); - (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); - assertEq(0, a); - assertEq(100, b); - } - - function testStorageCheckedWriteMapStructA() public { - stdstore - .target(address(test)) - .sig(test.map_struct.selector) - .with_key(address(this)) - .depth(0) - .checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 100); - assertEq(b, 0); - } - - function testStorageCheckedWriteMapStructB() public { - stdstore - .target(address(test)) - .sig(test.map_struct.selector) - .with_key(address(this)) - .depth(1) - .checked_write(100); - (uint256 a, uint256 b) = test.map_struct(address(this)); - assertEq(a, 0); - assertEq(b, 100); - } - - function testStorageStructA() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); - assertEq(uint256(7), slot); - } - - function testStorageStructB() public { - uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); - assertEq(uint256(7) + 1, slot); - } - - function testStorageCheckedWriteStructA() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 100); - assertEq(b, 1337); - } - - function testStorageCheckedWriteStructB() public { - stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); - (uint256 a, uint256 b) = test.basic(); - assertEq(a, 1337); - assertEq(b, 100); - } - - function testStorageMapAddrFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); - assertEq(uint256(keccak256(abi.encode(address(this), uint(1)))), slot); - } - - function testStorageMapUintFound() public { - uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); - assertEq(uint256(keccak256(abi.encode(100, uint(2)))), slot); - } - - function testStorageCheckedWriteMapUint() public { - stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); - assertEq(100, test.map_uint(100)); - } - - function testStorageCheckedWriteMapAddr() public { - stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); - assertEq(100, test.map_addr(address(this))); - } - - function testStorageCheckedWriteMapBool() public { - stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); - assertTrue(test.map_bool(address(this))); - } - - function testFailStorageCheckedWriteMapPacked() public { - // expect PackedSlot error but not external call so cant expectRevert - stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))).checked_write(100); - } - - function testStorageCheckedWriteMapPackedSuccess() public { - uint256 full = test.map_packed(address(1337)); - // keep upper 128, set lower 128 to 1337 - full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; - stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write(full); - assertEq(1337, test.read_struct_lower(address(1337))); - } - - function testFailStorageConst() public { - // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); - stdstore.target(address(test)).sig("const()").find(); - } - - function testFailStorageNativePack() public { - stdstore.target(address(test)).sig(test.tA.selector).find(); - stdstore.target(address(test)).sig(test.tB.selector).find(); - - // these both would fail - stdstore.target(address(test)).sig(test.tC.selector).find(); - stdstore.target(address(test)).sig(test.tD.selector).find(); - } -} - -contract StorageTest { - uint256 public exists = 1; - mapping(address => uint256) public map_addr; - mapping(uint256 => uint256) public map_uint; - mapping(address => uint256) public map_packed; - mapping(address => UnpackedStruct) public map_struct; - mapping(address => mapping(address => uint256)) public deep_map; - mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; - UnpackedStruct public basic; - - uint248 public tA; - bool public tB; - - - bool public tC = false; - uint248 public tD = 1; - - - struct UnpackedStruct { - uint256 a; - uint256 b; - } - - mapping(address => bool) public map_bool; - - constructor() { - basic = UnpackedStruct({ - a: 1337, - b: 1337 - }); - - uint256 two = (1<<128) | 1; - map_packed[msg.sender] = two; - map_packed[address(bytes20(uint160(1337)))] = 1<<128; - } - - function read_struct_upper(address who) public view returns (uint256) { - return map_packed[who] >> 128; - } - - function read_struct_lower(address who) public view returns (uint256) { - return map_packed[who] & ((1 << 128) - 1); - } - - function hidden() public view returns (bytes32 t) { - bytes32 slot = keccak256("my.random.var"); - assembly { - t := sload(slot) - } - } - - function const() public pure returns (bytes32 t) { - t = bytes32(hex"1337"); - } -} diff --git a/src/Bribe.sol b/src/Bribe.sol new file mode 100644 index 0000000..e69de29 diff --git a/src/MasterChef.sol b/src/MasterChef.sol index 0f2b489..121dccd 100644 --- a/src/MasterChef.sol +++ b/src/MasterChef.sol @@ -1,255 +1,302 @@ -// // SPDX-Identifier-License: MIT -// pragma solidity 0.8.20; +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; -// import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -// import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -// import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -// import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; -// import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; -// import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -// import {ISnake} from "./interfaces/ISnake.sol"; - -// /// @title MasterChef -// contract MasterChef is Ownable { -// using SafeCast for int256; -// using SafeERC20 for IERC20; - -// uint256 public constant DAY = 60 * 60 * 24; -// uint256 public constant WEEK = 7 * DAY; - -// struct StakerInfo { -// uint256 amount; // The amount of tokenIds which the user has staked -// int256 rewardDebt; -// uint256[] tokenIds; -// mapping(uint256 => uint256) tokenIndicates; -// } - -// struct PoolInfo { -// uint256 accRewardPerShare; -// uint256 lastRewardTime; -// } - -// // This is native protocol token -// ISnake public snake; - -// IERC721 public NFT; - -// // Reward token -// IERC20 public oSnake; - -// PoolInfo public poolInfo; - -// mapping(uint256 => address) public tokenOwner; - -// mapping(address => StakerInfo) public stakerInfo; - -// mapping(address => bool) public isKeeper; - -// uint256 public rewardPerSecond; -// uint256 public NATIVE_TOKEN_PRECISION; -// uint256 public distributePeriod; -// uint256 public lastDistributedTime; - -// /* -------------------------------------------------------------------------- */ -// /* EVENTS */ -// /* -------------------------------------------------------------------------- */ - -// event Deposit(address indexed user, uint256 amount, address indexed to); - -// event Withdraw(address indexed user, uint256 amount, address indexed to); - -// event Harvest(address indexed user, uint256 amount); - -// event PoolUpdated(uint256 lastRewardTime, uint256 nftSupply, uint256 accRewardPerShare); - -// event RewardPerSecondUpdated(uint256 rewardPerSeconds); - -// /* -------------------------------------------------------------------------- */ -// /* MODIFIERS */ -// /* -------------------------------------------------------------------------- */ - -// modifier onlyKeeper() { -// require(isKeeper[msg.sender], "MasterChef: FORBIDDEN"); -// _; -// } - -// constructor(IERC20 _nativeToken, IERC721 _nft) Ownable(msg.sender) { -// NATIVE_TOKEN = _nativeToken; -// NFT = _nft; -// distributePeriod = WEEK; -// // TODO: Consider to set the precision to ? -// NATIVE_TOKEN_PRECISION = 1e18; -// poolInfo = PoolInfo({lastRewardTime: block.timestamp, accRewardPerShare: 0}); -// } - -// function addKeeper(address[] memory _keepers) external onlyOwner { -// for (uint256 i = 0; i < _keepers.length;) { -// address _keeper = _keepers[i]; -// if (!isKeeper[_keeper]) { -// isKeeper[_keeper] = true; -// } -// unchecked { -// i++; -// } -// } -// } - -// function removeKeeper(address[] memory _keepers) external onlyOwner { -// uint256 i = 0; -// uint256 len = _keepers.length; - -// for (i; i < len;) { -// address _keeper = _keepers[i]; -// if (isKeeper[_keeper]) { -// isKeeper[_keeper] = false; -// } -// unchecked { -// i++; -// } -// } -// } - -// function setRewardPerSecond(uint256 _rewardPerSecond) public onlyOwner { -// updatePool(); -// rewardPerSecond = _rewardPerSecond; - -// emit RewardPerSecondUpdated(_rewardPerSecond); -// } - -// function setDistributeRate(uint256 amount) public onlyOwner { -// updatePool(); -// uint256 currentTime = block.timestamp; -// uint256 notDistributed; -// // Means that currentTime is within the week -// if (lastDistributedTime > 0 && currentTime < lastDistributedTime) { -// uint256 timeLeft; -// unchecked { -// timeLeft = lastDistributedTime - currentTime; -// } -// notDistributed = timeLeft * rewardPerSecond; -// } -// amount = amount + notDistributed; -// uint256 _rewardPerSecond = amount / distributePeriod; -// rewardPerSecond = _rewardPerSecond; -// lastDistributedTime = currentTime + distributePeriod; - -// emit RewardPerSecondUpdated(_rewardPerSecond); -// } - -// function updatePool() public returns (PoolInfo memory pool) { -// pool = poolInfo; -// if (block.timestamp > pool.lastRewardTime) { -// uint256 nftSupply = NFT.balanceOf(address(this)); -// uint256 currentTime = block.timestamp; -// if (nftSupply > 0) { -// uint256 time = currentTime > pool.lastRewardTime ? currentTime - pool.lastRewardTime : 0; -// uint256 reward = time * rewardPerSecond; -// pool.accRewardPerShare += reward * NATIVE_TOKEN_PRECISION / nftSupply; -// } -// pool.lastRewardTime = currentTime; -// poolInfo = pool; - -// emit PoolUpdated(pool.lastRewardTime, nftSupply, pool.accRewardPerShare); -// } -// } - -// /// @notice Deposit NFT token -// /// @dev Following the CEI principle -// function deposit(uint256[] calldata tokenIds) public { -// address sender = msg.sender; -// PoolInfo memory pool = updatePool(); -// StakerInfo storage staker = stakerInfo[sender]; - -// staker.amount = staker.amount + tokenIds.length; -// staker.rewardDebt = -// staker.rewardDebt + (int256(tokenIds.length * pool.accRewardPerShare / NATIVE_TOKEN_PRECISION)); - -// for (uint256 i = 0; i < tokenIds.length; i++) { -// require(NFT.ownerOf(tokenIds[i]) == sender, "MasterChef: INVALID_OWNER"); - -// staker.tokenIndicates[tokenIds[i]] = staker.tokenIds.length; -// staker.tokenIds.push(tokenIds[i]); -// tokenOwner[tokenIds[i]] = sender; - -// NFT.transferFrom(msg.sender, address(this), tokenIds[i]); -// } - -// emit Deposit(sender, tokenIds.length, msg.sender); -// } - -// /// @notice Withdraw the NFT tokens -// /// @dev Following the CEI principle -// function withdraw(uint256[] calldata tokenIds) public { -// address sender = msg.sender; -// PoolInfo memory pool = updatePool(); -// StakerInfo storage staker = stakerInfo[sender]; - -// staker.rewardDebt -= int256(tokenIds.length * pool.accRewardPerShare / NATIVE_TOKEN_PRECISION); -// staker.amount += tokenIds.length; - -// for (uint256 i = 0; i < tokenIds.length; i++) { -// require(tokenOwner[tokenIds[i]] == sender, "MasterChef: INVALID_OWNER"); - -// NFT.transferFrom(address(this), sender, tokenIds[i]); -// uint256 lastTokenId = staker.tokenIds[staker.tokenIds.length - 1]; -// staker.tokenIds[staker.tokenIndicates[tokenIds[i]]] = lastTokenId; -// staker.tokenIndicates[lastTokenId] = staker.tokenIndicates[tokenIds[i]]; -// staker.tokenIds.pop(); - -// delete staker.tokenIndicates[tokenIds[i]]; -// delete tokenOwner[tokenIds[i]]; -// } -// emit Withdraw(sender, tokenIds.length, sender); -// } - -// function harvest() public { -// address sender = msg.sender; -// PoolInfo memory pool = updatePool(); -// StakerInfo storage staker = stakerInfo[sender]; - -// int256 accumulatedReward = int256(staker.amount * pool.accRewardPerShare / NATIVE_TOKEN_PRECISION); -// uint256 _pendingReward = (accumulatedReward - staker.rewardDebt).toUint256(); - -// staker.rewardDebt = accumulatedReward; - -// if (_pendingReward > 0) { -// NATIVE_TOKEN.safeTransfer(sender, _pendingReward); -// } - -// emit Harvest(sender, _pendingReward); -// } - -// function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { -// return IERC721Receiver.onERC721Received.selector; -// } - -// /* -------------------------------------------------------------------------- */ -// /* VIEW FUNCTIONS */ -// /* -------------------------------------------------------------------------- */ - -// /// @notice View function to help see pending NATIVE_TOKEN on UI. -// /// @param _user User's address. -// /// @return pending The amount of pending NATIVE_TOKEN reward for a given user; -// function pendingReward(address _user) external view returns (uint256 pending) { -// PoolInfo memory pool = poolInfo; -// StakerInfo storage staker = stakerInfo[_user]; - -// uint256 accRewardPerShare = pool.accRewardPerShare; -// uint256 nftSupply = NFT.balanceOf(address(this)); -// uint256 currentTime = block.timestamp; - -// if (currentTime > pool.lastRewardTime && nftSupply != 0) { -// uint256 time; -// unchecked { -// time = currentTime - pool.lastRewardTime; -// } -// uint256 reward = time * rewardPerSecond; -// accRewardPerShare += reward * NATIVE_TOKEN_PRECISION / nftSupply; -// } -// pending = (int256(staker.amount * accRewardPerShare / NATIVE_TOKEN_PRECISION) - staker.rewardDebt).toUint256(); -// } - -// function stakedTokenIds(address _user) external view returns (uint256[] memory tokenIds) { -// tokenIds = stakerInfo[_user].tokenIds; -// } -// } +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {FixedPointMathLib} from "@solady/utils/FixedPointMathLib.sol"; + +import {ISnake} from "./interfaces/ISnake.sol"; + +/// @title MasterChef +contract MasterChef is Ownable { + using SafeCast for int256; + using SafeERC20 for IERC20; + using FixedPointMathLib for uint256; + + uint256 public constant DAY = 60 * 60 * 24; + uint256 public constant WEEK = 7 * DAY; + uint256 public constant WWND_PRECISION = 1e12; + + struct StakerInfo { + uint256 amount; // The amount of tokenIds which the user has staked + int256 rewardDebt; + uint256[] tokenIds; + mapping(uint256 => uint256) tokenIndicates; + } + + struct PoolInfo { + uint256 accRewardPerShare; + uint256 lastRewardTime; + } + + // This is native token + // ISnake public snake; + IERC20 public W_WND; + + IERC721 public NFT; + + /* --------------------------------- REWARD --------------------------------- */ + + ISnake public snakeToken; + + // IERC404 public snake404; + + PoolInfo public poolInfo; + + mapping(uint256 => address) public tokenOwner; + + mapping(address => StakerInfo) public stakerInfo; + + mapping(address => bool) public isKeeper; + + uint256 public rewardPerSecond; + uint256 public distributePeriod; + uint256 public lastDistributedTime; + + /* -------------------------------------------------------------------------- */ + /* EVENTS */ + /* -------------------------------------------------------------------------- */ + + event Deposit(address indexed user, uint256 amount, address indexed to); + + event Withdraw(address indexed user, uint256 amount, address indexed to); + + event Harvest(address indexed user, uint256 amount); + + event PoolUpdated( + uint256 lastRewardTime, + uint256 nftSupply, + uint256 accRewardPerShare + ); + + event RewardPerSecondUpdated(uint256 rewardPerSeconds); + + /* -------------------------------------------------------------------------- */ + /* MODIFIERS */ + /* -------------------------------------------------------------------------- */ + + modifier onlyKeeper() { + require(isKeeper[msg.sender], "MasterChef: FORBIDDEN"); + _; + } + + constructor(IERC20 _nativeToken, IERC721 _nft) Ownable(msg.sender) { + W_WND = _nativeToken; + NFT = _nft; + distributePeriod = WEEK; + poolInfo = PoolInfo({ + lastRewardTime: block.timestamp, + accRewardPerShare: 0 + }); + } + + function addKeeper(address[] memory _keepers) external onlyOwner { + for (uint256 i = 0; i < _keepers.length; ) { + address _keeper = _keepers[i]; + if (!isKeeper[_keeper]) { + isKeeper[_keeper] = true; + } + unchecked { + i++; + } + } + } + + function removeKeeper(address[] memory _keepers) external onlyOwner { + uint256 i = 0; + uint256 len = _keepers.length; + + for (i; i < len; ) { + address _keeper = _keepers[i]; + if (isKeeper[_keeper]) { + isKeeper[_keeper] = false; + } + unchecked { + i++; + } + } + } + + function setRewardPerSecond(uint256 _rewardPerSecond) public onlyOwner { + updatePool(); + rewardPerSecond = _rewardPerSecond; + + emit RewardPerSecondUpdated(_rewardPerSecond); + } + + function setDistributeRate(uint256 amount) public onlyOwner { + updatePool(); + uint256 currentTime = block.timestamp; + uint256 notDistributed; + // Means that currentTime is within the week + if (lastDistributedTime > 0 && currentTime < lastDistributedTime) { + uint256 timeLeft; + unchecked { + timeLeft = lastDistributedTime - currentTime; + } + notDistributed = timeLeft * rewardPerSecond; + } + amount = amount + notDistributed; + uint256 _rewardPerSecond = amount / distributePeriod; + rewardPerSecond = _rewardPerSecond; + lastDistributedTime = currentTime + distributePeriod; + + emit RewardPerSecondUpdated(_rewardPerSecond); + } + + function updatePool() public returns (PoolInfo memory pool) { + pool = poolInfo; + if (block.timestamp > pool.lastRewardTime) { + uint256 nftSupply = NFT.balanceOf(address(this)); + uint256 currentTime = block.timestamp; + if (nftSupply > 0) { + uint256 time = currentTime > pool.lastRewardTime + ? currentTime - pool.lastRewardTime + : 0; + uint256 reward = time * rewardPerSecond; + pool.accRewardPerShare += (reward * WWND_PRECISION) / nftSupply; + } + pool.lastRewardTime = currentTime; + poolInfo = pool; + + emit PoolUpdated( + pool.lastRewardTime, + nftSupply, + pool.accRewardPerShare + ); + } + } + + /// @notice Deposit NFT token + /// @dev Following the CEI principle + function deposit(uint256[] calldata tokenIds) public { + address sender = msg.sender; + PoolInfo memory pool = updatePool(); + StakerInfo storage staker = stakerInfo[sender]; + + staker.amount = staker.amount + tokenIds.length; + staker.rewardDebt = + staker.rewardDebt + + ( + int256( + (tokenIds.length * pool.accRewardPerShare) / WWND_PRECISION + ) + ); + + for (uint256 i = 0; i < tokenIds.length; i++) { + require( + NFT.ownerOf(tokenIds[i]) == sender, + "MasterChef: INVALID_OWNER" + ); + + staker.tokenIndicates[tokenIds[i]] = staker.tokenIds.length; + staker.tokenIds.push(tokenIds[i]); + tokenOwner[tokenIds[i]] = sender; + + NFT.transferFrom(msg.sender, address(this), tokenIds[i]); + } + + emit Deposit(sender, tokenIds.length, msg.sender); + } + + /// @notice Withdraw the NFT tokens + /// @dev Following the CEI principle + function withdraw(uint256[] calldata tokenIds) public { + address sender = msg.sender; + PoolInfo memory pool = updatePool(); + StakerInfo storage staker = stakerInfo[sender]; + + staker.rewardDebt -= int256( + (tokenIds.length * pool.accRewardPerShare) / WWND_PRECISION + ); + staker.amount += tokenIds.length; + + for (uint256 i = 0; i < tokenIds.length; i++) { + require( + tokenOwner[tokenIds[i]] == sender, + "MasterChef: INVALID_OWNER" + ); + + NFT.transferFrom(address(this), sender, tokenIds[i]); + uint256 lastTokenId = staker.tokenIds[staker.tokenIds.length - 1]; + staker.tokenIds[staker.tokenIndicates[tokenIds[i]]] = lastTokenId; + staker.tokenIndicates[lastTokenId] = staker.tokenIndicates[ + tokenIds[i] + ]; + staker.tokenIds.pop(); + + delete staker.tokenIndicates[tokenIds[i]]; + delete tokenOwner[tokenIds[i]]; + } + emit Withdraw(sender, tokenIds.length, sender); + } + + function harvest() public { + address sender = msg.sender; + PoolInfo memory pool = updatePool(); + StakerInfo storage staker = stakerInfo[sender]; + + int256 accumulatedReward = int256( + (staker.amount * pool.accRewardPerShare) / WWND_PRECISION + ); + uint256 _pendingReward = (accumulatedReward - staker.rewardDebt) + .toUint256(); + + staker.rewardDebt = accumulatedReward; + + if (_pendingReward > 0) { + W_WND.safeTransfer(sender, _pendingReward); + } + + emit Harvest(sender, _pendingReward); + } + + function onERC721Received( + address, + address, + uint256, + bytes calldata + ) external pure returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; + } + + /* -------------------------------------------------------------------------- */ + /* VIEW FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + + /// @notice View function to help see pending W_WND on UI. + /// @param _user User's address. + /// @return pending The amount of pending W_WND reward for a given user; + function pendingReward( + address _user + ) external view returns (uint256 pending) { + PoolInfo memory pool = poolInfo; + StakerInfo storage staker = stakerInfo[_user]; + + uint256 accRewardPerShare = pool.accRewardPerShare; + uint256 nftSupply = NFT.balanceOf(address(this)); + uint256 currentTime = block.timestamp; + + if (currentTime > pool.lastRewardTime && nftSupply != 0) { + uint256 time; + unchecked { + time = currentTime - pool.lastRewardTime; + } + uint256 reward = time * rewardPerSecond; + accRewardPerShare += (reward * WWND_PRECISION) / nftSupply; + } + pending = (int256( + (staker.amount * accRewardPerShare) / WWND_PRECISION + ) - staker.rewardDebt).toUint256(); + } + + function stakedTokenIds( + address _user + ) external view returns (uint256[] memory tokenIds) { + tokenIds = stakerInfo[_user].tokenIds; + } +} diff --git a/src/snakeForFun/OSnake.sol b/src/OSnake.sol similarity index 100% rename from src/snakeForFun/OSnake.sol rename to src/OSnake.sol diff --git a/src/Snake.sol b/src/Snake.sol index dcd406f..917bc45 100644 --- a/src/Snake.sol +++ b/src/Snake.sol @@ -1,108 +1,120 @@ -// // SPDX-Identifier-License: MIT -// pragma solidity 0.8.20; - -// import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; - -// import {IERC20Metadata} from "./interfaces/IERC20Metadata.sol"; -// import {ISnake} from "./interfaces/ISnake.sol"; -// import {IERC404Operator} from "./interfaces/IERC404Operator.sol"; -// import {ERC721Receiver} from "./ERC721Receiver.sol"; - -// contract Snake is ISnake, IERC20Metadata, ERC721Receiver { - -// string public override name; - -// string public override symbol; - -// uint8 public immutable override decimals; - -// uint256 public immutable override totalSupply; - -// mapping(address => uint256) public override balanceOf; - -// mapping(address => mapping(address => uint256)) public override allowance; - -// mapping(uint256 => address) public override getApproved; - -// mapping(address => mapping(address => bool)) public override isApprovedForAll; - -// mapping(uint256 => address) internal _ownerOf; - -// mapping(address => uint256[]) internal _owned; - -// mapping(uint256 => uint256) internal _ownedIndex; - -// mapping(address => bool) public whitelist; - -// IERC404Operator public operator; - -// address public router; - -// address public factory; - -// /* --------------------------------- EVENTS --------------------------------- */ - -// event ERC20Transfer(address indexed from , address indexed to, uint256 amount); - -// event Approval(address indexed owner, address indexed spender, uint256 amount); - -// event Transfer(address indexed from, address indexed to, uint256 amount); - -// event ERC721Transfer(address indexed from, address indexed to, uint256 id); - -// event ApprovalForAll(address indexed owner, address indexed operator, bool approved); - -// /* -------------------------------------------------------------------------- */ -// /* ERRORS */ -// /* -------------------------------------------------------------------------- */ -// error NotFound(); -// error AlreadyExists(); -// error InvalidRecipient(); -// error InvalidSender(); -// error UnsafeRecipient(); - -// constructor( -// string memory _name, -// string memory _symbol, -// address _nft, -// address _router, -// address _factory; -// ) { -// name = _name; -// symbol = _symbol; -// nft = IERC721(_nft); -// router = _router; -// factory = _factory; -// } - -// function snakeNFT(uint256 tokenId) external { -// require(!migrated[tokenId], "Already migrated"); -// address sender = msg.sender; -// require(sender == nft.ownerOf(tokenId), "Not the owner of the NFT"); - -// // TODO: Mint token for nft owner; -// } - -// /* -------------------------------------------------------------------------- */ -// /* INTERNAL FUNCTIONS */ -// /* -------------------------------------------------------------------------- */ -// function _transfer(address from, address to, uint256 amount) internal returns (bool) { -// require(from != address(0), 'ERC20: transfer from the zero address'); -// uint256 balanceBeforeSender = balanceOf[from]; -// uint256 balanceBeforeReceiver = balanceOf[to]; - -// balanceOf[from] -= amount; - -// unchecked { -// balanceOf[to] += amount; -// } - -// if (operator.approveOperator(address(this), from)) { -// uint256 -// } -// } - -// function _getUnit() internal view returns (uint256) { -// return 10 ** decimals(); -// } -// } +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +contract Snake is Ownable { + string public constant name = "S_N_A_K_E"; + string public constant symbol = "SNAKE"; + + uint8 public constant decimals = 18; + uint256 public totalSupply = 0; + + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + + bool public initialMinted; + address public minter; + address public redemptionReceiver; + address public merkleClaim; + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval( + address indexed owner, + address indexed spender, + uint256 value + ); + + constructor(address _owner) Ownable(_owner) { + _mint(msg.sender, 0); + } + + /* -------------------------------------------------------------------------- */ + /* EXTERNAL FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + + // No checks as its meant to be once off to set minting rights to BaseV1 Minter + function setMinter(address _minter) external { + require(msg.sender == minter); + minter = _minter; + } + + function setRedemptionReceiver(address _receiver) external { + require(msg.sender == minter); + redemptionReceiver = _receiver; + } + + function setMerkleClaim(address _merkleClaim) external { + require(msg.sender == minter); + merkleClaim = _merkleClaim; + } + + // NFTs are minted from this amount as well now + function initialMint(address _recipient) external { + require(msg.sender == minter && !initialMinted); + initialMinted = true; + _mint(_recipient, 400 * 1e6 * 1e18); //#settings + } + + function approve(address _spender, uint256 _value) external returns (bool) { + allowance[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + return true; + } + + function transfer(address _to, uint256 _value) external returns (bool) { + return _transfer(msg.sender, _to, _value); + } + + function transferFrom( + address _from, + address _to, + uint256 _value + ) external returns (bool) { + uint256 allowed_from = allowance[_from][msg.sender]; + if (allowed_from != type(uint256).max) { + allowance[_from][msg.sender] -= _value; + } + return _transfer(_from, _to, _value); + } + + function mint(address account, uint256 amount) external returns (bool) { + require(msg.sender == minter); + _mint(account, amount); + return true; + } + + function claim(address account, uint256 amount) external returns (bool) { + require(msg.sender == redemptionReceiver || msg.sender == merkleClaim); + _mint(account, amount); + return true; + } + + /* ---------------------------- PUBLIC FUNCTIONS ---------------------------- */ + + /* -------------------------------------------------------------------------- */ + /* INTERNAL FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + + function _mint(address _to, uint256 _amount) internal returns (bool) { + totalSupply += _amount; + unchecked { + balanceOf[_to] += _amount; + } + emit Transfer(address(0x0), _to, _amount); + return true; + } + + function _transfer( + address _from, + address _to, + uint256 _value + ) internal returns (bool) { + balanceOf[_from] -= _value; + unchecked { + balanceOf[_to] += _value; + } + emit Transfer(_from, _to, _value); + return true; + } +} diff --git a/src/Voting.sol b/src/Voting.sol new file mode 100644 index 0000000..e69de29 diff --git a/src/VotingEscrow.sol b/src/VotingEscrow.sol index 0592153..5db1054 100644 --- a/src/VotingEscrow.sol +++ b/src/VotingEscrow.sol @@ -22,7 +22,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME, MERGE_TYPE, - SPLIT_TYPE + SPLIT_TYPE } struct LockedBalance { @@ -36,6 +36,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint ts; uint blk; // block } + /* We cannot really do block numbers per se b/c slope is per time, not per block * and per block could be fairly bad b/c Ethereum changes blocktimes. * What we can do is to extrapolate ***At functions */ @@ -88,7 +89,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint internal tokenId; /// @notice Contract constructor - /// @param token_addr `SAE` token address + /// @param token_addr `S_N_A_K_E` token address constructor(address token_addr, address art_proxy) { token = token_addr; voter = msg.sender; @@ -127,10 +128,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { METADATA STORAGE //////////////////////////////////////////////////////////////*/ - string constant public name = "veThena"; - string constant public symbol = "veTHE"; - string constant public version = "1.0.0"; - uint8 constant public decimals = 18; + string public constant name = "ve_S_N_A_K_E"; + string public constant symbol = "veSNAKE"; + string public constant version = "1.0.0"; + uint8 public constant decimals = 18; function setTeam(address _team) external { require(msg.sender == team); @@ -145,9 +146,18 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @dev Returns current token URI metadata /// @param _tokenId Token ID to fetch URI for. function tokenURI(uint _tokenId) external view returns (string memory) { - require(idToOwner[_tokenId] != address(0), "Query for nonexistent token"); + require( + idToOwner[_tokenId] != address(0), + "Query for nonexistent token" + ); LockedBalance memory _locked = locked[_tokenId]; - return IVeArtProxy(artProxy)._tokenURI(_tokenId,_balanceOfNFT(_tokenId, block.timestamp),_locked.end,uint(int256(_locked.amount))); + return + IVeArtProxy(artProxy)._tokenURI( + _tokenId, + _balanceOfNFT(_tokenId, block.timestamp), + _locked.end, + uint(int256(_locked.amount)) + ); } /*////////////////////////////////////////////////////////////// @@ -201,7 +211,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @dev Checks if `_operator` is an approved operator for `_owner`. /// @param _owner The address that owns the NFTs. /// @param _operator The address that acts on behalf of the owner. - function isApprovedForAll(address _owner, address _operator) external view returns (bool) { + function isApprovedForAll( + address _owner, + address _operator + ) external view returns (bool) { return (ownerToOperators[_owner])[_operator]; } @@ -259,7 +272,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _spender address of the spender to query /// @param _tokenId uint ID of the token to be transferred /// @return bool whether the msg.sender is approved for the given token ID, is an operator of the owner, or is the owner of the token - function _isApprovedOrOwner(address _spender, uint _tokenId) internal view returns (bool) { + function _isApprovedOrOwner( + address _spender, + uint _tokenId + ) internal view returns (bool) { address owner = idToOwner[_tokenId]; bool spenderIsOwner = owner == _spender; bool spenderIsApproved = _spender == idToApprovals[_tokenId]; @@ -267,7 +283,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { return spenderIsOwner || spenderIsApproved || spenderIsApprovedForAll; } - function isApprovedOrOwner(address _spender, uint _tokenId) external view returns (bool) { + function isApprovedOrOwner( + address _spender, + uint _tokenId + ) external view returns (bool) { return _isApprovedOrOwner(_spender, _tokenId); } @@ -309,11 +328,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _from The current owner of the NFT. /// @param _to The new owner. /// @param _tokenId The NFT to transfer. - function transferFrom( - address _from, - address _to, - uint _tokenId - ) external { + function transferFrom(address _from, address _to, uint _tokenId) external { _transferFrom(_from, _to, _tokenId, msg.sender); } @@ -369,13 +384,24 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { if (_isContract(_to)) { // Throws if transfer destination is a contract which does not implement 'onERC721Received' - try IERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) returns (bytes4 response) { - if (response != IERC721Receiver(_to).onERC721Received.selector) { + try + IERC721Receiver(_to).onERC721Received( + msg.sender, + _from, + _tokenId, + _data + ) + returns (bytes4 response) { + if ( + response != IERC721Receiver(_to).onERC721Received.selector + ) { revert("ERC721: ERC721Receiver rejected tokens"); } } catch (bytes memory reason) { if (reason.length == 0) { - revert('ERC721: transfer to non ERC721Receiver implementer'); + revert( + "ERC721: transfer to non ERC721Receiver implementer" + ); } else { assembly { revert(add(32, reason), mload(reason)) @@ -391,7 +417,9 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @dev Interface identification is specified in ERC-165. /// @param _interfaceID Id of the interface - function supportsInterface(bytes4 _interfaceID) external view returns (bool) { + function supportsInterface( + bytes4 _interfaceID + ) external view returns (bool) { return supportedInterfaces[_interfaceID]; } @@ -406,7 +434,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { mapping(uint => uint) internal tokenToOwnerIndex; /// @dev Get token by index - function tokenOfOwnerByIndex(address _owner, uint _tokenIndex) external view returns (uint) { + function tokenOfOwnerByIndex( + address _owner, + uint _tokenIndex + ) external view returns (uint) { return ownerToNFTokenIdList[_owner][_tokenIndex]; } @@ -494,7 +525,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } function _burn(uint _tokenId) internal { - require(_isApprovedOrOwner(msg.sender, _tokenId), "caller is not owner nor approved"); + require( + _isApprovedOrOwner(msg.sender, _tokenId), + "caller is not owner nor approved" + ); address owner = ownerOf(_tokenId); @@ -505,7 +539,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { // Remove token //_removeTokenFrom(msg.sender, _tokenId); _removeTokenFrom(owner, _tokenId); - + emit Transfer(owner, address(0), _tokenId); } @@ -522,6 +556,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint internal constant WEEK = 1 weeks; uint internal constant MAXTIME = 2 * 365 * 86400; + uint internal constant MINTIME = 7 * 24 * 60 * 60; // 7 days int128 internal constant iMAXTIME = 2 * 365 * 86400; uint internal constant MULTIPLIER = 1 ether; @@ -541,7 +576,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _tokenId token of the NFT /// @param _idx User epoch number /// @return Epoch time of the checkpoint - function user_point_history__ts(uint _tokenId, uint _idx) external view returns (uint) { + function user_point_history__ts( + uint _tokenId, + uint _idx + ) external view returns (uint) { return user_point_history[_tokenId][_idx].ts; } @@ -572,11 +610,15 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { // Kept at zero when they have to if (old_locked.end > block.timestamp && old_locked.amount > 0) { u_old.slope = old_locked.amount / iMAXTIME; - u_old.bias = u_old.slope * int128(int256(old_locked.end - block.timestamp)); + u_old.bias = + u_old.slope * + int128(int256(old_locked.end - block.timestamp)); } if (new_locked.end > block.timestamp && new_locked.amount > 0) { u_new.slope = new_locked.amount / iMAXTIME; - u_new.bias = u_new.slope * int128(int256(new_locked.end - block.timestamp)); + u_new.bias = + u_new.slope * + int128(int256(new_locked.end - block.timestamp)); } // Read values of scheduled changes in the slope @@ -592,7 +634,12 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } } - Point memory last_point = Point({bias: 0, slope: 0, ts: block.timestamp, blk: block.number}); + Point memory last_point = Point({ + bias: 0, + slope: 0, + ts: block.timestamp, + blk: block.number + }); if (_epoch > 0) { last_point = point_history[_epoch]; } @@ -603,7 +650,9 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { Point memory initial_last_point = last_point; uint block_slope = 0; // dblock/dt if (block.timestamp > last_point.ts) { - block_slope = (MULTIPLIER * (block.number - last_point.blk)) / (block.timestamp - last_point.ts); + block_slope = + (MULTIPLIER * (block.number - last_point.blk)) / + (block.timestamp - last_point.ts); } // If last point is already recorded in this block, slope=0 // But that's ok b/c we know the block in such case @@ -621,7 +670,9 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } else { d_slope = slope_changes[t_i]; } - last_point.bias -= last_point.slope * int128(int256(t_i - last_checkpoint)); + last_point.bias -= + last_point.slope * + int128(int256(t_i - last_checkpoint)); last_point.slope += d_slope; if (last_point.bias < 0) { // This can happen @@ -633,7 +684,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } last_checkpoint = t_i; last_point.ts = t_i; - last_point.blk = initial_last_point.blk + (block_slope * (t_i - initial_last_point.ts)) / MULTIPLIER; + last_point.blk = + initial_last_point.blk + + (block_slope * (t_i - initial_last_point.ts)) / + MULTIPLIER; _epoch += 1; if (t_i == block.timestamp) { last_point.blk = block.number; @@ -726,11 +780,21 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { _checkpoint(_tokenId, old_locked, _locked); address from = msg.sender; - if (_value != 0 && deposit_type != DepositType.MERGE_TYPE && deposit_type != DepositType.SPLIT_TYPE ) { + if ( + _value != 0 && deposit_type != DepositType.MERGE_TYPE + // && deposit_type != DepositType.SPLIT_TYPE + ) { assert(IERC20(token).transferFrom(from, address(this), _value)); } - emit Deposit(from, _tokenId, _value, _locked.end, deposit_type, block.timestamp); + emit Deposit( + from, + _tokenId, + _value, + _locked.end, + deposit_type, + block.timestamp + ); emit Supply(supply_before, supply_before + _value); } @@ -752,34 +816,66 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { LockedBalance memory _locked = locked[_tokenId]; require(_value > 0); // dev: need non-zero value - require(_locked.amount > 0, 'No existing lock found'); - require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); - _deposit_for(_tokenId, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE); + require(_locked.amount > 0, "No existing lock found"); + require( + _locked.end > block.timestamp, + "Cannot add to expired lock. Withdraw" + ); + _deposit_for( + _tokenId, + _value, + 0, + _locked, + DepositType.DEPOSIT_FOR_TYPE + ); } /// @notice Deposit `_value` tokens for `_to` and lock for `_lock_duration` /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit - function _create_lock(uint _value, uint _lock_duration, address _to) internal returns (uint) { - uint unlock_time = (block.timestamp + _lock_duration) / WEEK * WEEK; // Locktime is rounded down to weeks + function _create_lock( + uint _value, + uint _lock_duration, + address _to + ) internal returns (uint) { + uint unlock_time = ((block.timestamp + _lock_duration) / WEEK) * WEEK; // Locktime is rounded down to weeks require(_value > 0); // dev: need non-zero value - require(unlock_time > block.timestamp, 'Can only lock until time in the future'); - require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 2 years max'); + require( + unlock_time > block.timestamp, + "Can only lock until time in the future" + ); + require( + unlock_time <= block.timestamp + MAXTIME, + "Voting lock can be 2 years max" + ); + require( + unlock_time >= block.timestamp + MINTIME, + "Voting lock must be 7 days minimum" + ); ++tokenId; uint _tokenId = tokenId; _mint(_to, _tokenId); - _deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.CREATE_LOCK_TYPE); + _deposit_for( + _tokenId, + _value, + unlock_time, + locked[_tokenId], + DepositType.CREATE_LOCK_TYPE + ); return _tokenId; } /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lock_duration` /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) - function create_lock(uint _value, uint _lock_duration) external nonreentrant returns (uint) { + function create_lock( + uint _value, + uint _lock_duration + ) external nonreentrant returns (uint) { return _create_lock(_value, _lock_duration, msg.sender); } @@ -787,7 +883,11 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _value Amount to deposit /// @param _lock_duration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit - function create_lock_for(uint _value, uint _lock_duration, address _to) external nonreentrant returns (uint) { + function create_lock_for( + uint _value, + uint _lock_duration, + address _to + ) external nonreentrant returns (uint) { return _create_lock(_value, _lock_duration, _to); } @@ -799,26 +899,47 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { LockedBalance memory _locked = locked[_tokenId]; assert(_value > 0); // dev: need non-zero value - require(_locked.amount > 0, 'No existing lock found'); - require(_locked.end > block.timestamp, 'Cannot add to expired lock. Withdraw'); + require(_locked.amount > 0, "No existing lock found"); + require( + _locked.end > block.timestamp, + "Cannot add to expired lock. Withdraw" + ); - _deposit_for(_tokenId, _value, 0, _locked, DepositType.INCREASE_LOCK_AMOUNT); + _deposit_for( + _tokenId, + _value, + 0, + _locked, + DepositType.INCREASE_LOCK_AMOUNT + ); } /// @notice Extend the unlock time for `_tokenId` /// @param _lock_duration New number of seconds until tokens unlock - function increase_unlock_time(uint _tokenId, uint _lock_duration) external nonreentrant { + function increase_unlock_time( + uint _tokenId, + uint _lock_duration + ) external nonreentrant { assert(_isApprovedOrOwner(msg.sender, _tokenId)); LockedBalance memory _locked = locked[_tokenId]; - uint unlock_time = (block.timestamp + _lock_duration) / WEEK * WEEK; // Locktime is rounded down to weeks + uint unlock_time = ((block.timestamp + _lock_duration) / WEEK) * WEEK; // Locktime is rounded down to weeks - require(_locked.end > block.timestamp, 'Lock expired'); - require(_locked.amount > 0, 'Nothing is locked'); - require(unlock_time > _locked.end, 'Can only increase lock duration'); - require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 2 years max'); + require(_locked.end > block.timestamp, "Lock expired"); + require(_locked.amount > 0, "Nothing is locked"); + require(unlock_time > _locked.end, "Can only increase lock duration"); + require( + unlock_time <= block.timestamp + MAXTIME, + "Voting lock can be 2 years max" + ); - _deposit_for(_tokenId, 0, unlock_time, _locked, DepositType.INCREASE_UNLOCK_TIME); + _deposit_for( + _tokenId, + 0, + unlock_time, + _locked, + DepositType.INCREASE_UNLOCK_TIME + ); } /// @notice Withdraw all tokens for `_tokenId` @@ -831,14 +952,14 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { require(block.timestamp >= _locked.end, "The lock didn't expire"); uint value = uint(int256(_locked.amount)); - locked[_tokenId] = LockedBalance(0,0); + locked[_tokenId] = LockedBalance(0, 0); uint supply_before = supply; supply = supply_before - value; // old_locked can have either expired <= timestamp or zero end // _locked has only 0 end // Both can have >= 0 amount - _checkpoint(_tokenId, _locked, LockedBalance(0,0)); + _checkpoint(_tokenId, _locked, LockedBalance(0, 0)); assert(IERC20(token).transfer(msg.sender, value)); @@ -861,7 +982,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _block Block to find /// @param max_epoch Don't go beyond this epoch /// @return Approximate timestamp for block - function _find_block_epoch(uint _block, uint max_epoch) internal view returns (uint) { + function _find_block_epoch( + uint _block, + uint max_epoch + ) internal view returns (uint) { // Binary search uint _min = 0; uint _max = max_epoch; @@ -885,13 +1009,18 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _tokenId NFT for lock /// @param _t Epoch time to return voting power at /// @return User voting power - function _balanceOfNFT(uint _tokenId, uint _t) internal view returns (uint) { + function _balanceOfNFT( + uint _tokenId, + uint _t + ) internal view returns (uint) { uint _epoch = user_point_epoch[_tokenId]; if (_epoch == 0) { return 0; } else { Point memory last_point = user_point_history[_tokenId][_epoch]; - last_point.bias -= last_point.slope * int128(int256(_t) - int256(last_point.ts)); + last_point.bias -= + last_point.slope * + int128(int256(_t) - int256(last_point.ts)); if (last_point.bias < 0) { last_point.bias = 0; } @@ -904,7 +1033,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { return _balanceOfNFT(_tokenId, block.timestamp); } - function balanceOfNFTAt(uint _tokenId, uint _t) external view returns (uint) { + function balanceOfNFTAt( + uint _tokenId, + uint _t + ) external view returns (uint) { return _balanceOfNFT(_tokenId, _t); } @@ -913,7 +1045,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param _tokenId User's wallet NFT /// @param _block Block to calculate the voting power at /// @return Voting power - function _balanceOfAtNFT(uint _tokenId, uint _block) internal view returns (uint) { + function _balanceOfAtNFT( + uint _tokenId, + uint _block + ) internal view returns (uint) { // Copying and pasting totalSupply code because Vyper cannot pass by // reference yet assert(_block <= block.number); @@ -962,7 +1097,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } } - function balanceOfAtNFT(uint _tokenId, uint _block) external view returns (uint) { + function balanceOfAtNFT( + uint _tokenId, + uint _block + ) external view returns (uint) { return _balanceOfAtNFT(_tokenId, _block); } @@ -979,11 +1117,15 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { if (target_epoch < _epoch) { Point memory point_next = point_history[target_epoch + 1]; if (point.blk != point_next.blk) { - dt = ((_block - point.blk) * (point_next.ts - point.ts)) / (point_next.blk - point.blk); + dt = + ((_block - point.blk) * (point_next.ts - point.ts)) / + (point_next.blk - point.blk); } } else { if (point.blk != block.number) { - dt = ((_block - point.blk) * (block.timestamp - point.ts)) / (block.number - point.blk); + dt = + ((_block - point.blk) * (block.timestamp - point.ts)) / + (block.number - point.blk); } } // Now dt contains info on how far are we beyond point @@ -993,7 +1135,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { /// @param point The point (bias/slope) to start search from /// @param t Time to calculate the total voting power at /// @return Total voting power at that time - function _supply_at(Point memory point, uint t) internal view returns (uint) { + function _supply_at( + Point memory point, + uint t + ) internal view returns (uint) { Point memory last_point = point; uint t_i = (last_point.ts / WEEK) * WEEK; for (uint i = 0; i < 255; ++i) { @@ -1004,7 +1149,9 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } else { d_slope = slope_changes[t_i]; } - last_point.bias -= last_point.slope * int128(int256(t_i - last_point.ts)); + last_point.bias -= + last_point.slope * + int128(int256(t_i - last_point.ts)); if (t_i == t) { break; } @@ -1080,14 +1227,12 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { _deposit_for(_to, value0, end, _locked1, DepositType.MERGE_TYPE); } - /** * @notice split NFT into multiple * @param amounts % of split * @param _tokenId NFTs ID */ function split(uint[] memory amounts, uint _tokenId) external { - // check permission and vote require(attachments[_tokenId] == 0 && !voted[_tokenId], "attached"); require(_isApprovedOrOwner(msg.sender, _tokenId)); @@ -1098,13 +1243,13 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { uint end = _locked.end; uint value = uint(int256(_locked.amount)); require(value > 0); // dev: need non-zero value - + // reset supply, _deposit_for increase it supply = supply - value; uint i; uint totalWeight = 0; - for(i = 0; i < amounts.length; i++){ + for (i = 0; i < amounts.length; i++) { totalWeight += amounts[i]; } @@ -1115,19 +1260,30 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { // save end uint unlock_time = end; - require(unlock_time > block.timestamp, 'Can only lock until time in the future'); - require(unlock_time <= block.timestamp + MAXTIME, 'Voting lock can be 2 years max'); - - // mint + require( + unlock_time > block.timestamp, + "Can only lock until time in the future" + ); + require( + unlock_time <= block.timestamp + MAXTIME, + "Voting lock can be 2 years max" + ); + + // mint uint _value = 0; - for(i = 0; i < amounts.length; i++){ + for (i = 0; i < amounts.length; i++) { ++tokenId; _tokenId = tokenId; _mint(_to, _tokenId); - _value = value * amounts[i] / totalWeight; - _deposit_for(_tokenId, _value, unlock_time, locked[_tokenId], DepositType.SPLIT_TYPE); - } - + _value = (value * amounts[i]) / totalWeight; + _deposit_for( + _tokenId, + _value, + unlock_time, + locked[_tokenId], + DepositType.SPLIT_TYPE + ); + } } /*/////////////////////////////////////////////////////////////// @@ -1135,10 +1291,14 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { //////////////////////////////////////////////////////////////*/ /// @notice The EIP-712 typehash for the contract's domain - bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); + bytes32 public constant DOMAIN_TYPEHASH = + keccak256( + "EIP712Domain(string name,uint256 chainId,address verifyingContract)" + ); /// @notice The EIP-712 typehash for the delegation struct used by the contract - bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); + bytes32 public constant DELEGATION_TYPEHASH = + keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); /// @notice A record of each accounts delegate mapping(address => address) private _delegates; @@ -1173,7 +1333,8 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { if (nCheckpoints == 0) { return 0; } - uint[] storage _tokenIds = checkpoints[account][nCheckpoints - 1].tokenIds; + uint[] storage _tokenIds = checkpoints[account][nCheckpoints - 1] + .tokenIds; uint votes = 0; for (uint i = 0; i < _tokenIds.length; i++) { uint tId = _tokenIds[i]; @@ -1182,7 +1343,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { return votes; } - function getPastVotesIndex(address account, uint timestamp) public view returns (uint32) { + function getPastVotesIndex( + address account, + uint timestamp + ) public view returns (uint32) { uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; @@ -1213,11 +1377,10 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { return lower; } - function getPastVotes(address account, uint timestamp) - public - view - returns (uint) - { + function getPastVotes( + address account, + uint timestamp + ) public view returns (uint) { uint32 _checkIndex = getPastVotesIndex(account, timestamp); // Sum votes uint[] storage _tokenIds = checkpoints[account][_checkIndex].tokenIds; @@ -1230,7 +1393,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { return votes; } - function getPastTotalSupply(uint256 timestamp) external view returns (uint) { + function getPastTotalSupply(uint256 timestamp) public view returns (uint) { return totalSupplyAtT(timestamp); } @@ -1250,9 +1413,8 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ? checkpoints[srcRep][srcRepNum - 1].tokenIds : checkpoints[srcRep][0].tokenIds; uint32 nextSrcRepNum = _findWhatCheckpointToWrite(srcRep); - uint[] storage srcRepNew = checkpoints[srcRep][ - nextSrcRepNum - ].tokenIds; + uint[] storage srcRepNew = checkpoints[srcRep][nextSrcRepNum] + .tokenIds; // All the same except _tokenId for (uint i = 0; i < srcRepOld.length; i++) { uint tId = srcRepOld[i]; @@ -1270,9 +1432,8 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ? checkpoints[dstRep][dstRepNum - 1].tokenIds : checkpoints[dstRep][0].tokenIds; uint32 nextDstRepNum = _findWhatCheckpointToWrite(dstRep); - uint[] storage dstRepNew = checkpoints[dstRep][ - nextDstRepNum - ].tokenIds; + uint[] storage dstRepNew = checkpoints[dstRep][nextDstRepNum] + .tokenIds; // All the same plus _tokenId require( dstRepOld.length + 1 <= MAX_DELEGATES, @@ -1289,11 +1450,9 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { } } - function _findWhatCheckpointToWrite(address account) - internal - view - returns (uint32) - { + function _findWhatCheckpointToWrite( + address account + ) internal view returns (uint32) { uint _timestamp = block.timestamp; uint32 _nCheckPoints = numCheckpoints[account]; @@ -1320,9 +1479,8 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ? checkpoints[srcRep][srcRepNum - 1].tokenIds : checkpoints[srcRep][0].tokenIds; uint32 nextSrcRepNum = _findWhatCheckpointToWrite(srcRep); - uint[] storage srcRepNew = checkpoints[srcRep][ - nextSrcRepNum - ].tokenIds; + uint[] storage srcRepNew = checkpoints[srcRep][nextSrcRepNum] + .tokenIds; // All the same except what owner owns for (uint i = 0; i < srcRepOld.length; i++) { uint tId = srcRepOld[i]; @@ -1340,9 +1498,8 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ? checkpoints[dstRep][dstRepNum - 1].tokenIds : checkpoints[dstRep][0].tokenIds; uint32 nextDstRepNum = _findWhatCheckpointToWrite(dstRep); - uint[] storage dstRepNew = checkpoints[dstRep][ - nextDstRepNum - ].tokenIds; + uint[] storage dstRepNew = checkpoints[dstRep][nextDstRepNum] + .tokenIds; uint ownerTokenCount = ownerToNFTokenCount[owner]; require( dstRepOld.length + ownerTokenCount <= MAX_DELEGATES, @@ -1393,7 +1550,7 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ) public { require(delegatee != msg.sender); require(delegatee != address(0)); - + bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, @@ -1424,4 +1581,4 @@ contract VotingEscrow is IERC721, IERC721Metadata, IVotes { ); return _delegate(signatory, delegatee); } -} \ No newline at end of file +} diff --git a/src/dex/WrappedWND.sol b/src/dex/WrappedWND.sol index 0927f05..36b9237 100644 --- a/src/dex/WrappedWND.sol +++ b/src/dex/WrappedWND.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.20; contract WrappedWND { - uint8 public constant decimals = 12; + uint8 public constant decimals = 18; mapping(address => uint256) public balanceOf; @@ -48,16 +48,14 @@ contract WrappedWND { function transfer(address _to, uint256 _amount) external returns (bool) { require(balanceOf[msg.sender] >= _amount, "WrappedWND: INSUFFICIENT_BALANCE"); - _transfer(msg.sender, _to, _amount); - return true; + return _transfer(msg.sender, _to, _amount); } function transferFrom(address _from, address _to, uint256 _amount) external returns(bool) { require(balanceOf[_from] >= _amount, "WrappedWND: INSUFFICIENT_BALANCE"); require(allowance[_from][msg.sender] >= _amount, "WrappedWND: INSUFFICIENT_ALLOWANCE"); allowance[_from][msg.sender] -= _amount; - _transfer(_from, _to, _amount); - return true; + return _transfer(_from, _to, _amount); } function _transfer(address _from, address _to, uint256 _amount) internal returns(bool) { diff --git a/src/governance/SnakeGovernor.sol b/src/governance/SnakeGovernor.sol new file mode 100644 index 0000000..ab4047a --- /dev/null +++ b/src/governance/SnakeGovernor.sol @@ -0,0 +1,73 @@ +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {IGovernor} from "@openzeppelin/contracts/governance/IGovernor.sol"; +import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol"; + +import {Governor} from "./abstract/Governor.sol"; +import {GovernorVotes} from "./abstract/GovernorVotes.sol"; +import {GovernorVotesQuorumFraction} from "./abstract/GovernorVotesQuorumFraction.sol"; +import {GovernorCountingSimple} from "./abstract/GovernorCountingSimple.sol"; + +contract SnakeGovernor is + Governor, + GovernorCountingSimple, + GovernorVotes, + GovernorVotesQuorumFraction +{ + uint256 public constant MAX_NUMERATOR = 100; // max 10% + uint256 public constant DENOMINATOR = 1000; + uint256 public constant MAX_PROPOSAL_THRESHOLD = 1000; + + address public setter; + uint256 public numerator = 3; // 0.03 % + + constructor( + IVotes _veSnake + ) + Governor("S_N_A_K_E__G_O_V_E_R_N_O_R") + GovernorVotes(_veSnake) + GovernorVotesQuorumFraction(4) // 4% + { + setter = msg.sender; + } + + function votingDelay() public pure override returns (uint256) { + return 15 * 60; // 15 minutes + } + + function votingPeriod() public pure override returns (uint256) { + return 7 * 24 * 60 * 60; // 7 days + } + + function setSetter(address _setter) external { + require(msg.sender == setter, "Not Setter"); + setter = _setter; + } + + function setProposalNumerator(uint256 _numerator) external { + require(msg.sender == setter, "Not Setter"); + require(numerator <= MAX_NUMERATOR, "Not Exceed max"); + numerator = _numerator; + } + + function proposalThreshold() + public + view + virtual + override(Governor) + returns (uint256) + { + return + (token.getPastTotalSupply(block.timestamp) * numerator) / + DENOMINATOR; + } + + function CLOCK_MODE() public pure override returns (string memory) { + return "mode=timestamp"; + } + + function clock() public view override returns (uint48) { + return uint48(block.timestamp); + } +} diff --git a/src/governance/abstract/Governor.sol b/src/governance/abstract/Governor.sol new file mode 100644 index 0000000..524bfa0 --- /dev/null +++ b/src/governance/abstract/Governor.sol @@ -0,0 +1,593 @@ +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; +import {DoubleEndedQueue} from "@openzeppelin/contracts/utils/structs/DoubleEndedQueue.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; +import {Context} from "@openzeppelin/contracts/utils/Context.sol"; +import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; +import {Nonces} from "@openzeppelin/contracts/utils/Nonces.sol"; + +import {IGovernor} from "@openzeppelin/contracts/governance/IGovernor.sol"; + +/// @title Governor +/// @author Modified from https://github.com/withtally/rollcall/blob/main/src/standards/L2Governor.sol +abstract contract Governor is + Context, + ERC165, + EIP712, + IGovernor, + Nonces, + IERC721Receiver, + IERC1155Receiver +{ + using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; + using SafeCast for uint256; + + bytes32 public constant BALLOT_TYPEHASH = + keccak256("Ballot(uint256 proposalId,uint8 support)"); + bytes32 public ADVANCED_BALLOT_TYPEHASH = + keccak256( + "AdvancedBallot(uint256 proposalId,uint8 support,string reason)" + ); + + struct ProposalCore { + address proposer; + uint256 voteStart; + uint256 voteEnd; + bool executed; + bool canceled; + // uint48 etaSeconds; + } + + string private _name; + + mapping(uint256 => ProposalCore) private _proposals; + + DoubleEndedQueue.Bytes32Deque private _governanceCalls; + + modifier onlyGovernance() { + require(_msgSender() == _executor(), "Governor: FORBIDDEN"); + if (_executor() != address(this)) { + bytes32 msgDataHash = keccak256(_msgData()); + while (_governanceCalls.popFront() != msgDataHash) {} + } + _; + } + + constructor(string memory _name_) EIP712(_name_, version()) { + _name = _name_; + } + + function onERC721Received( + address, + address, + uint256, + bytes memory + ) public virtual override returns (bytes4) { + return this.onERC721Received.selector; + } + + function onERC1155Received( + address, + address, + uint256, + uint256, + bytes memory + ) public virtual override returns (bytes4) { + return this.onERC1155Received.selector; + } + + function onERC1155BatchReceived( + address, + address, + uint256[] memory, + uint256[] memory, + bytes memory + ) public virtual override returns (bytes4) { + return this.onERC1155BatchReceived.selector; + } + + receive() external payable virtual { + require(_executor() == address(this)); + } + + function propose( + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + string memory _description + ) public virtual override returns (uint256 proposalId) { + require( + getVotes(_msgSender(), block.timestamp - 1) >= proposalThreshold(), + "Governor: proposer votes below proposal threshold" + ); + + proposalId = hashProposal( + _targets, + _values, + _calldatas, + keccak256(bytes(_description)) + ); + + require( + _targets.length == _values.length, + "Governor: invalid proposal length" + ); + require( + _targets.length == _calldatas.length, + "Governor: invalid proposal length" + ); + require(_targets.length > 0, "Governor: empty proposal"); + + ProposalCore storage proposal = _proposals[proposalId]; + require(proposal.voteStart == 0, "Governor: proposal already exists"); + uint64 start = block.timestamp.toUint64() - votingDelay().toUint64(); + uint256 end = start + votingPeriod().toUint64(); + proposal.proposer = _msgSender(); + proposal.voteStart = start; + proposal.voteEnd = end; + + emit ProposalCreated( + proposalId, + _msgSender(), + _targets, + _values, + new string[](_targets.length), + _calldatas, + start, + end, + _description + ); + } + + function cancel( + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + bytes32 _descriptionHash + ) public virtual override returns (uint256 proposalId) { + proposalId = hashProposal( + _targets, + _values, + _calldatas, + _descriptionHash + ); + + ProposalState status = state(proposalId); + + require( + status != ProposalState.Pending, + "Governor: proposal not active" + ); + if (_msgSender() != proposalProposer(proposalId)) { + revert GovernorOnlyProposer(_msgSender()); + } + + return _cancel(_targets, _values, _calldatas, _descriptionHash); + } + + function queue( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) public virtual override returns (uint256 proposalId) {} + + function execute( + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + bytes32 _descriptionHash + ) public payable virtual override returns (uint256 proposalId) { + proposalId = hashProposal( + _targets, + _values, + _calldatas, + _descriptionHash + ); + + ProposalState status = state(proposalId); + + require( + status == ProposalState.Queued || status == ProposalState.Succeeded, + "Governor: proposal not successfully" + ); + _proposals[proposalId].executed = true; + + emit ProposalExecuted(proposalId); + + _beforeExecute( + proposalId, + _targets, + _values, + _calldatas, + _descriptionHash + ); + _execute(proposalId, _targets, _values, _calldatas, _descriptionHash); + _afterExecute( + proposalId, + _targets, + _values, + _calldatas, + _descriptionHash + ); + } + + function castVote( + uint256 _proposalId, + uint8 _support + ) public virtual returns (uint256) { + address voter = _msgSender(); + return _castVote(_proposalId, voter, _support, ""); + } + + function castVoteWithReason( + uint256 _proposalId, + uint8 _support, + string memory _reason + ) public virtual returns (uint256) { + address voter = _msgSender(); + return _castVote(_proposalId, voter, _support, _reason); + } + + function castVoteWithReasonAndParams( + uint256 _proposalId, + uint8 _support, + string calldata _reason, + bytes memory // params + ) public virtual returns (uint256) { + address voter = _msgSender(); + return _castVote(_proposalId, voter, _support, _reason); + } + + function castVoteBySig( + uint256 _proposalId, + uint8 _support, + address _voter, + bytes memory _signature + ) public virtual override returns (uint256) { + bool valid = SignatureChecker.isValidSignatureNow( + _voter, + _hashTypedDataV4( + keccak256( + abi.encode(BALLOT_TYPEHASH, _proposalId, _support, _voter) + ) + ), + _signature + ); + if (!valid) { + revert("Governor: invalid signature"); + } + return _castVote(_proposalId, _voter, _support, ""); + } + + function castVoteWithReasonAndParamsBySig( + uint256 _proposalId, + uint8 _support, + address _voter, + string memory _reason, + bytes memory _params, + bytes memory _signature + ) public virtual returns (uint256) { + bool valid = SignatureChecker.isValidSignatureNow( + _voter, + _hashTypedDataV4( + keccak256( + abi.encode( + ADVANCED_BALLOT_TYPEHASH, + _proposalId, + _support, + _voter, + _useNonce(_voter), + keccak256(bytes(_reason)), + keccak256(_params) + ) + ) + ), + _signature + ); + if (!valid) { + revert("Governor: invalid signature"); + } + return _castVote(_proposalId, _voter, _support, _reason, _params); + } + + function relay( + address _target, + uint256 _value, + bytes memory _params + ) external virtual onlyGovernance { + Address.functionCallWithValue(_target, _params, _value); + } + + /* -------------------------------------------------------------------------- */ + /* VIEW FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(IERC165, ERC165) returns (bool) { + return + interfaceId == type(IGovernor).interfaceId || + super.supportsInterface(interfaceId); + } + + function name() public view virtual override returns (string memory) { + return _name; + } + + function version() public pure override returns (string memory) { + return "1.0.0"; + } + + function hashProposal( + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + bytes32 _descriptionHash + ) public pure virtual override returns (uint256) { + return + uint256( + keccak256( + abi.encode(_targets, _values, _calldatas, _descriptionHash) + ) + ); + } + + function state(uint256 _proposalId) public view returns (ProposalState) { + ProposalCore storage proposal = _proposals[_proposalId]; + + if (proposal.executed) { + return ProposalState.Executed; + } + + if (proposal.canceled) { + return ProposalState.Canceled; + } + + uint256 startTime = proposalSnapshot(_proposalId); + + if (startTime == 0) { + revert("Governor: proposal not found"); + } + + if (block.timestamp < startTime) { + return ProposalState.Pending; + } + + uint256 deadline = proposalDeadline(_proposalId); + if (block.timestamp <= deadline) { + return ProposalState.Active; + } + + if (_quorumReached(_proposalId) && _voteSucceeded(_proposalId)) { + return ProposalState.Succeeded; + } else { + return ProposalState.Defeated; + } + } + + function proposalSnapshot( + uint256 _proposalId + ) public view virtual override returns (uint256) { + return _proposals[_proposalId].voteStart; + } + + function proposalDeadline( + uint256 _proposalId + ) public view virtual override returns (uint256) { + return _proposals[_proposalId].voteEnd; + } + + function proposalThreshold() public view virtual returns (uint256) { + return 0; + } + + function getVotes( + address _account, + uint256 _blockTimestamp + ) public view virtual override returns (uint256) { + return _getVotes(_account, _blockTimestamp, _defaultParams()); + } + + function getVotesWithParams( + address _account, + uint256 _blockTimestamp, + bytes memory _params + ) public view virtual override returns (uint256) { + return _getVotes(_account, _blockTimestamp, _params); + } + + function proposalEta( + uint256 // proposalId + ) public view virtual override returns (uint256) { + return 0; + } + + function proposalNeedsQueuing( + uint256 + ) public view virtual override returns (bool) { + return false; + } + + function proposalProposer( + uint256 proposalId + ) public view virtual override returns (address) { + return _proposals[proposalId].proposer; + } + + function clock() public view virtual returns (uint48); + + function CLOCK_MODE() public view virtual returns (string memory); + + function votingDelay() public view virtual returns (uint256); + + function votingPeriod() public view virtual returns (uint256); + + function quorum(uint256 timestamp) public view virtual returns (uint256); + + /* -------------------------------------------------------------------------- */ + /* INTERNAL FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + + function _beforeExecute( + uint256, // _proposalId + address[] memory _targets, + uint256[] memory, // _values + bytes[] memory _calldatas, + bytes32 // _descriptionHash + ) internal virtual { + if (_executor() != address(this)) { + for (uint256 i = 0; i < _targets.length; i++) { + if (_targets[i] == address(this)) { + _governanceCalls.pushBack(keccak256(_calldatas[i])); + } + } + } + } + + function _afterExecute( + uint256, // _proposalId + address[] memory, // _targets + uint256[] memory, // _values + bytes[] memory, // _calldatas + bytes32 // _descriptionHash + ) internal virtual { + if (_executor() != address(this)) { + if (!_governanceCalls.empty()) { + _governanceCalls.clear(); + } + } + } + + function _execute( + uint256, // _proposalId + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + bytes32 // _descriptionHash + ) internal { + for (uint256 i = 0; i < _targets.length; i++) { + (bool success, bytes memory data) = _targets[i].call{ + value: _values[i] + }(_calldatas[i]); + Address.verifyCallResult(success, data); + } + } + + function _cancel( + address[] memory _targets, + uint256[] memory _values, + bytes[] memory _calldatas, + bytes32 _descriptionHash + ) internal virtual returns (uint256 proposalId) { + proposalId = hashProposal( + _targets, + _values, + _calldatas, + _descriptionHash + ); + ProposalState status = state(proposalId); + + require( + status != ProposalState.Canceled && + status != ProposalState.Expired && + status != ProposalState.Executed, + "Governor: proposal not active" + ); + _proposals[proposalId].canceled = true; + emit ProposalCanceled(proposalId); + } + + function _castVote( + uint256 _proposalId, + address _account, + uint8 _support, + string memory _reason + ) internal virtual returns (uint256) { + return + _castVote( + _proposalId, + _account, + _support, + _reason, + _defaultParams() + ); + } + + function _castVote( + uint256 _proposalId, + address _account, + uint8 _support, + string memory _reason, + bytes memory _params + ) internal virtual returns (uint256 totalWeight) { + ProposalCore storage proposal = _proposals[_proposalId]; + require( + state(_proposalId) == ProposalState.Active, + "Governor: voting not currently active" + ); + totalWeight = _getVotes(_account, proposal.voteStart, _params); + _countVote(_proposalId, _account, _support, totalWeight, _params); + if (_params.length == 0) { + emit VoteCast( + _account, + _proposalId, + _support, + totalWeight, + _reason + ); + } else { + emit VoteCastWithParams( + _account, + _proposalId, + _support, + totalWeight, + _reason, + _params + ); + } + } + + /// @notice Must to override this function + /// @dev Check whether the quorum of the proposal reached + function _quorumReached( + uint256 _proposalId + ) internal view virtual returns (bool); + + /// @notice Must to override this function + /// @dev Check whether the vote succeeded + function _voteSucceeded( + uint256 _proposalId + ) internal view virtual returns (bool); + + /// @dev Register a vote with a given support and voting weight + function _countVote( + uint256 _proposalId, + address _account, + uint8 _support, + uint256 weight, + bytes memory params + ) internal virtual returns (uint256); + + function _getVotes( + address _account, + uint256 _blockTimestamp, + bytes memory _params + ) internal view virtual returns (uint256); + + function _defaultParams() internal view virtual returns (bytes memory) { + return ""; + } + + function _executor() internal view virtual returns (address) { + return address(this); + } +} diff --git a/src/governance/abstract/GovernorCountingSimple.sol b/src/governance/abstract/GovernorCountingSimple.sol new file mode 100644 index 0000000..74f0eba --- /dev/null +++ b/src/governance/abstract/GovernorCountingSimple.sol @@ -0,0 +1,101 @@ +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {Governor} from "./Governor.sol"; + +abstract contract GovernorCountingSimple is Governor { + enum VoteType { + Against, + For, + Abstain + } + + struct ProposalVote { + uint256 againstVotes; + uint256 forVotes; + uint256 abstainVotes; + mapping(address => bool) hasVoted; + } + + mapping(uint256 => ProposalVote) internal _proposalVotes; + + function COUNTING_MODE() + public + pure + virtual + override + returns (string memory) + { + return "support=bravo&quorum=for,abstain"; + } + + function hasVoted( + uint256 _proposalId, + address _account + ) public view virtual override returns (bool) { + return _proposalVotes[_proposalId].hasVoted[_account]; + } + + function proposalVotes( + uint256 _proposalId + ) + public + view + virtual + returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) + { + ProposalVote storage proposalVote = _proposalVotes[_proposalId]; + return ( + proposalVote.againstVotes, + proposalVote.forVotes, + proposalVote.abstainVotes + ); + } + + /* -------------------------------------------------------------------------- */ + /* INTERNAL FUNCTIONS */ + /* -------------------------------------------------------------------------- */ + function _quorumReached( + uint256 _proposalId + ) internal view virtual override returns (bool) { + ProposalVote storage proposalVote = _proposalVotes[_proposalId]; + return + quorum(proposalSnapshot(_proposalId)) <= + proposalVote.forVotes + proposalVote.abstainVotes; + } + + function _voteSucceeded( + uint256 _proposalId + ) internal view virtual override returns (bool) { + ProposalVote storage proposalVote = _proposalVotes[_proposalId]; + return proposalVote.forVotes > proposalVote.againstVotes; + } + + function _countVote( + uint256 _proposalId, + address _account, + uint8 _support, + uint256 _weight, + bytes memory // _params + ) internal virtual override returns (uint256) { + ProposalVote storage proposalVote = _proposalVotes[_proposalId]; + + require( + !proposalVote.hasVoted[_account], + "Governor: account has already voted" + ); + proposalVote.hasVoted[_account] = true; + + if (_support == uint8(VoteType.Against)) { + proposalVote.againstVotes += _weight; + } else if (_support == uint8(VoteType.For)) { + proposalVote.forVotes += _weight; + } else if (_support == uint8(VoteType.Abstain)) { + proposalVote.abstainVotes += _weight; + } else { + revert("Governor: invalid vote type"); + } + + return _weight; + } +} diff --git a/src/governance/abstract/GovernorVotes.sol b/src/governance/abstract/GovernorVotes.sol new file mode 100644 index 0000000..b73aee7 --- /dev/null +++ b/src/governance/abstract/GovernorVotes.sol @@ -0,0 +1,22 @@ +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol"; + +import {Governor} from "./Governor.sol"; + +abstract contract GovernorVotes is Governor { + IVotes public immutable token; + + constructor(IVotes _token) { + token = _token; + } + + function _getVotes( + address _account, + uint256 _blockNumber, + bytes memory // _params + ) internal view virtual override returns (uint256) { + return token.getPastVotes(_account, _blockNumber); + } +} diff --git a/src/governance/abstract/GovernorVotesQuorumFraction.sol b/src/governance/abstract/GovernorVotesQuorumFraction.sol new file mode 100644 index 0000000..a9b2a69 --- /dev/null +++ b/src/governance/abstract/GovernorVotesQuorumFraction.sol @@ -0,0 +1,54 @@ +// SPDX-Identifier-License: MIT +pragma solidity 0.8.20; + +import {GovernorVotes} from "./GovernorVotes.sol"; + +abstract contract GovernorVotesQuorumFraction is GovernorVotes { + uint256 private _quorumNumerator; + + /* --------------------------------- EVENTS --------------------------------- */ + event QuorumNumeratorUpdated( + uint256 oldQuorumNumerator, + uint256 newQuorumNumerator + ); + + constructor(uint256 _quorumNumerator_) { + _quorumNumerator = _quorumNumerator_; + } + + function quorumNumerator() public view virtual returns (uint256) { + return _quorumNumerator; + } + function quorumDenominator() public pure virtual returns (uint256) { + return 100; + } + + function quorum( + uint256 blockNumber + ) public view virtual override returns (uint256) { + return + (quorumNumerator() * token.getPastTotalSupply(blockNumber)) / + quorumDenominator(); + } + + function updateQuorumNumerator( + uint256 _newQuorumNumerator + ) external virtual onlyGovernance { + _updateQuorumNumerator(_newQuorumNumerator); + } + + /* --------------------------- INTERNAL FUNCTIONS --------------------------- */ + function _updateQuorumNumerator( + uint256 _newQuorumNumerator + ) internal virtual { + require( + _newQuorumNumerator <= quorumDenominator(), + "GovernorVotesQuorumFraction: quorumNumerator > quorumDenominator" + ); + + uint256 oldQuorumNumerator = _quorumNumerator; + _quorumNumerator = _newQuorumNumerator; + + emit QuorumNumeratorUpdated(oldQuorumNumerator, _newQuorumNumerator); + } +} diff --git a/src/interfaces/IVotingEscrow.sol b/src/interfaces/IVotingEscrow.sol index b274770..72cfa57 100644 --- a/src/interfaces/IVotingEscrow.sol +++ b/src/interfaces/IVotingEscrow.sol @@ -13,7 +13,10 @@ interface IVotingEscrow { function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); - function user_point_history(uint tokenId, uint loc) external view returns (Point memory); + function user_point_history( + uint tokenId, + uint loc + ) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); diff --git a/src/snakeForFun/SnakeForFun.sol b/src/snakeForFun/SnakeForFun.sol index 878cc67..7a119f9 100644 --- a/src/snakeForFun/SnakeForFun.sol +++ b/src/snakeForFun/SnakeForFun.sol @@ -1,4 +1,160 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.20; -contract SnakeForFun {} \ No newline at end of file +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +/// @title S_N_A_K_E__F_O_R__F_U_N +/// @notice This contract is used to airdrop S_N_A_K_E tokens to users for fun +contract SnakeForFun { + using ECDSA for bytes32; + + address public team; + + IERC20 public snakeToken; + + struct Snake { + uint256 snapshotTime; + address signer; + uint256 totalSnake; + mapping(address => bool) snaked; + } + + /// @dev current turn id + uint256 internal snakeId; + + /// @dev snakes + mapping(uint256 => Snake) internal snakes; + + bytes32 public immutable EIP712_DOMAIN; + + bytes32 public constant SUPPORT_TYPEHASH = + keccak256("ForFun(address forFunGuy,uint256 amount)"); + + uint256 public constant MAX_ALLOCATION = 5; + + /// @dev allocation + mapping(uint256 => mapping(uint256 => uint256)) internal allocations; + + /* -------------------------------------------------------------------------- */ + /* EVENTS */ + /* -------------------------------------------------------------------------- */ + + event BitedForFun( + uint256 indexed turnId, + address indexed forFunGuy, + uint256 amount, + uint256 snapshotTime + ); + + event ForFun(address indexed forFunGuy, uint256 amount); + + constructor(address _team, address _snakeToken) { + team = _team; + snakeToken = IERC20(_snakeToken); + + EIP712_DOMAIN = keccak256( + abi.encode( + keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ), + keccak256(bytes("SnakeForFun")), + keccak256(bytes("v1")), + block.chainid, + address(this) + ) + ); + } + + modifier onlyTeam() { + require(msg.sender == team, "SnakeForFun: FORBIDDEN"); + _; + } + + function biteForFun( + uint256 totalSnake, + address signer, + uint256[] memory allocation + ) external onlyTeam { + require( + totalSnake <= MAX_ALLOCATION && totalSnake > 0, + "SnakeForFun: INVALID_ALLOCATION" + ); + require( + totalSnake == allocation.length, + "SnakeForFun: INVALID_ALLOCATION" + ); + snakeId++; + Snake storage snake = snakes[snakeId]; + snake.signer = signer; + snake.totalSnake = totalSnake; + snake.snapshotTime = block.timestamp; + for (uint256 i = 0; i < totalSnake; ) { + allocations[snakeId][i] = allocation[i]; + unchecked { + i++; + } + } + + emit BitedForFun(snakeId, signer, totalSnake, block.timestamp); + } + + function forFun( + uint256 _turnId, + bytes calldata _signature, + address _guy, + uint256 _amount + ) external { + Snake storage snake = snakes[_turnId]; + require(!snake.snaked[_guy], "SnakeForFun: ALREADY_SNAKED"); + + bytes32 digest = toTypedDataHash(_guy, _amount); + address sigSigner = digest.recover(_signature); + + require(sigSigner == snake.signer, "SnakeForFun: INVALID_SIGNATURE"); + + require(sigSigner != address(0), "SnakeForFun: INVALID_SIGNATURE"); + + snakes[_turnId].snaked[_guy] = true; + snakeToken.transfer(_guy, _amount); + + emit ForFun(_guy, _amount); + } + + function snapshotTime(uint256 _turnId) external view returns (uint256) { + return snakes[_turnId].snapshotTime; + } + + function totalSnake(uint256 _turnId) external view returns (uint256) { + return snakes[_turnId].totalSnake; + } + + function signer(uint256 _turnId) external view returns (address) { + return snakes[_turnId].signer; + } + + function snaked( + uint256 _turnId, + address _guy + ) external view returns (bool) { + return snakes[_turnId].snaked[_guy]; + } + + function allocation( + uint256 _turnId, + uint256 _index + ) external view returns (uint256) { + return allocations[_turnId][_index]; + } + + function toTypedDataHash( + address _forFunGuy, + uint256 _amount + ) public view returns (bytes32) { + bytes32 structHash = keccak256( + abi.encode(SUPPORT_TYPEHASH, _forFunGuy, _amount) + ); + return MessageHashUtils.toTypedDataHash(EIP712_DOMAIN, structHash); + } +} diff --git a/test/BaseTest.sol b/test/BaseTest.t.sol similarity index 82% rename from test/BaseTest.sol rename to test/BaseTest.t.sol index 28fac72..58f35e4 100644 --- a/test/BaseTest.sol +++ b/test/BaseTest.t.sol @@ -1,10 +1,9 @@ // SPDX-Identifier-License: MIT pragma solidity 0.8.20; -import {Test} from "forge-std/Test.sol"; +import {Test, console} from "lib/forge-std/src/Test.sol"; // import {Snake} from "../src/Snake.sol"; - abstract contract BaseTest is Test { uint256 public constant INITIAL_SUPPLY = 1000000 * 10 ** 18; @@ -17,10 +16,10 @@ abstract contract BaseTest is Test { address[] public users; function setUp() public virtual { - moonbaseFork = vm.createFork('moonbase'); + moonbaseFork = vm.createFork("moonbase"); vm.selectFork(moonbaseFork); - owner = makeAddr("owner"); + // owner = makeAddr("owner"); // stablecoinMinter = makeAddr("stablecoinMinter"); // snakeStablecoin = new SnakeStablecoin(stablecoinMinter); diff --git a/test/SnakeForFun.t.sol b/test/SnakeForFun.t.sol new file mode 100644 index 0000000..1837e0a --- /dev/null +++ b/test/SnakeForFun.t.sol @@ -0,0 +1,48 @@ +// // SPDX-License-Identifier: MIT +// pragma solidity 0.8.20; + +// import {Test, console} from "lib/forge-std/src/Test.sol"; +// import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +// import {SnakeForFun} from "../src/snakeForFun/SnakeForFun.sol"; +// import {Snake} from "../src/Snake.sol"; + +// contract SnakeForFunTest is Test { +// address public owner; +// Snake public snakeToken; +// SnakeForFun public snakeForFun; + +// vm.Wallet public signer; + +// function setUp() public { +// owner = makeAddr("owner"); +// signer = vm.createWallet(); +// snakeToken = new Snake(owner); +// snakeForFun = new SnakeForFun(owner, address(snakeToken)); +// } + +// function test_forFun() public { +// address guy = makeAddr("guy"); +// uint256 amount = 1000; + +// // _biteForFun(signer., totalSnake, allocation); +// } + +// function _biteForFun( +// address _signer, +// uint256 totalSnake, +// uint256[] memory allocation +// ) internal { +// vm.prank(owner); +// snakeForFun.biteForFun(_signer, totalSnake, allocation); +// } + +// function _sign( +// bytes32 digest, +// uint256 privateKey +// ) internal returns (bytes32 signature) { +// (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); + +// signature = abi.encodePacked(r, s, v); +// } +// } diff --git a/test/WrappedWND.sol b/test/WrappedWND.t.sol similarity index 94% rename from test/WrappedWND.sol rename to test/WrappedWND.t.sol index 05f02b1..1a2d0a5 100644 --- a/test/WrappedWND.sol +++ b/test/WrappedWND.t.sol @@ -1,12 +1,11 @@ // SPDX-Identifier-License: MIT pragma solidity 0.8.20; -import "@forge-std/Test.sol"; +import {Test, console} from "../lib/forge-std/src/Test.sol"; import {WrappedWND} from "../src/dex/WrappedWND.sol"; contract WrappedWNDTest is Test { - WrappedWND public wrappedWND; address public owner = makeAddr("owner"); @@ -34,9 +33,9 @@ contract WrappedWNDTest is Test { vm.prank(user); wrappedWND.deposit{value: amount}(); assertEq(wrappedWND.balanceOf(user), amount); - + vm.prank(user); wrappedWND.withdraw(amount); assertEq(wrappedWND.balanceOf(user), 0); } -} \ No newline at end of file +}