Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions assignments/savage_assignment/Solidity_Assignment/todo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Node modules
/node_modules

# Compilation output
/dist

# pnpm deploy output
/bundle

# Hardhat Build Artifacts
/artifacts

# Hardhat compilation (v2) support directory
/cache

# Typechain output
/types

# Hardhat coverage reports
/coverage
57 changes: 57 additions & 0 deletions assignments/savage_assignment/Solidity_Assignment/todo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Sample Hardhat 3 Beta Project (`mocha` and `ethers`)

This project showcases a Hardhat 3 Beta project using `mocha` for tests and the `ethers` library for Ethereum interactions.

To learn more about the Hardhat 3 Beta, please visit the [Getting Started guide](https://hardhat.org/docs/getting-started#getting-started-with-hardhat-3). To share your feedback, join our [Hardhat 3 Beta](https://hardhat.org/hardhat3-beta-telegram-group) Telegram group or [open an issue](https://github.com/NomicFoundation/hardhat/issues/new) in our GitHub issue tracker.

## Project Overview

This example project includes:

- A simple Hardhat configuration file.
- Foundry-compatible Solidity unit tests.
- TypeScript integration tests using `mocha` and ethers.js
- Examples demonstrating how to connect to different types of networks, including locally simulating OP mainnet.

## Usage

### Running Tests

To run all the tests in the project, execute the following command:

```shell
npx hardhat test
```

You can also selectively run the Solidity or `mocha` tests:

```shell
npx hardhat test solidity
npx hardhat test mocha
```

### Make a deployment to Sepolia

This project includes an example Ignition module to deploy the contract. You can deploy this module to a locally simulated chain or to Sepolia.

To run the deployment to a local chain:

```shell
npx hardhat ignition deploy ignition/modules/Counter.ts
```

To run the deployment to Sepolia, you need an account with funds to send the transaction. The provided Hardhat configuration includes a Configuration Variable called `SEPOLIA_PRIVATE_KEY`, which you can use to set the private key of the account you want to use.

You can set the `SEPOLIA_PRIVATE_KEY` variable using the `hardhat-keystore` plugin or by setting it as an environment variable.

To set the `SEPOLIA_PRIVATE_KEY` config variable using `hardhat-keystore`:

```shell
npx hardhat keystore set SEPOLIA_PRIVATE_KEY
```

After setting the variable, you can run the deployment with the Sepolia network:

```shell
npx hardhat ignition deploy --network sepolia ignition/modules/Counter.ts
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

contract Counter {
uint public x;

event Increment(uint by);

function inc() public {
x++;
emit Increment(1);
}

function incBy(uint by) public {
require(by > 0, "incBy: increment should be positive");
x += by;
emit Increment(by);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

import {Counter} from "./Counter.sol";
import {Test} from "forge-std/Test.sol";

// Solidity tests are compatible with foundry, so they
// use the same syntax and offer the same functionality.

contract CounterTest is Test {
Counter counter;

function setUp() public {
counter = new Counter();
}

function test_InitialValue() public view {
require(counter.x() == 0, "Initial value should be 0");
}

function testFuzz_Inc(uint8 x) public {
for (uint8 i = 0; i < x; i++) {
counter.inc();
}
require(counter.x() == x, "Value after calling inc x times should be x");
}

function test_IncByZero() public {
vm.expectRevert();
counter.incBy(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;


contract Todo{
uint256 todoCounter;

enum Status {
Pending,
Done,
Cancelled,
Defaulted
}


struct TodoList{
uint id;
address owner;
string text;
Status status;
uint256 deadline;
}


mapping(uint => TodoList) todos;
event TodoCreated(string text, uint deadline);



function createTodo(string memory _text, uint _deadline) external returns (uint) {
require(bytes(_text).length > 0, "Empty text");
require(_deadline > (block.timestamp + 600), "Invalid deadline");

todoCounter++;

todos[todoCounter] = TodoList(todoCounter, msg.sender, _text, Status.Pending, _deadline);


emit TodoCreated(_text, _deadline);
return todoCounter++;
}


function UpdateTodo(uint _id) external {
require((_id > 0) && (_id <= todoCounter), 'invalid id');
TodoList storage todo = todos[_id];
require(todo.status == Status.Pending, "Not pending");
require(msg.sender == todo.owner, "unauthorized Caller");


if(block.timestamp > todo.deadline){
todo.status = Status.Defaulted;
}
else {
todo.status = Status.Done;
}


todo.status = Status.Done;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import "dotenv/config";
import hardhatToolboxMochaEthersPlugin from "@nomicfoundation/hardhat-toolbox-mocha-ethers";
import { configVariable, defineConfig } from "hardhat/config";

export default defineConfig({
plugins: [hardhatToolboxMochaEthersPlugin],
solidity: {
profiles: {
default: {
version: "0.8.28",
},
production: {
version: "0.8.28",
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
},
},
networks: {
hardhatMainnet: {
type: "edr-simulated",
chainType: "l1",
},
hardhatOp: {
type: "edr-simulated",
chainType: "op",
},
sepolia: {
type: "http",
chainType: "l1",
url: configVariable("SEPOLIA_RPC_URL"),
accounts: [configVariable("SEPOLIA_PRIVATE_KEY")],
},
},
verify: {
etherscan: {
apiKey: configVariable("ETHERSCAN_API_KEY"),
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"_format": "hh3-artifact-1",
"contractName": "Todo",
"sourceName": "contracts/todo.sol",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "text",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
}
],
"name": "TodoCreated",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"name": "UpdateTodo",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_text",
"type": "string"
},
{
"internalType": "uint256",
"name": "_deadline",
"type": "uint256"
}
],
"name": "createTodo",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x6080604052348015600e575f5ffd5b5061063d8061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c80632a8fb18a14610038578063ece28c6c1461004d575b5f5ffd5b61004b610046366004610359565b610072565b005b61006061005b366004610384565b6101b6565b60405190815260200160405180910390f35b5f8111801561008257505f548111155b6100c05760405162461bcd60e51b815260206004820152600a6024820152691a5b9d985b1a59081a5960b21b60448201526064015b60405180910390fd5b5f8181526001602052604081209060038083015460ff16908111156100e7576100e7610439565b146101225760405162461bcd60e51b815260206004820152600b60248201526a4e6f742070656e64696e6760a81b60448201526064016100b7565b60018101546001600160a01b031633146101745760405162461bcd60e51b81526020600482015260136024820152723ab730baba3437b934bd32b21021b0b63632b960691b60448201526064016100b7565b8060040154421115610195576003818101805460ff191690911790556101a5565b60038101805460ff191660011790555b600301805460ff1916600117905550565b5f5f8351116101f45760405162461bcd60e51b815260206004820152600a602482015269115b5c1d1e481d195e1d60b21b60448201526064016100b7565b61020042610258610461565b82116102415760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420646561646c696e6560801b60448201526064016100b7565b5f8054908061024f83610474565b90915550506040805160a0810182525f80548252336020830152918101859052906060820190815260209081018490525f805481526001808352604091829020845181559284015190830180546001600160a01b0319166001600160a01b0390921691909117905582015160028201906102c99082610510565b506060820151816003015f6101000a81548160ff021916908360038111156102f3576102f3610439565b0217905550608082015181600401559050507f022c3fffe570decf2328dbf4f2af598df5112da7e31568af8b927c48276ccae383836040516103369291906105cb565b60405180910390a15f8054908061034c83610474565b9190505590505b92915050565b5f60208284031215610369575f5ffd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215610395575f5ffd5b823567ffffffffffffffff8111156103ab575f5ffd5b8301601f810185136103bb575f5ffd5b803567ffffffffffffffff8111156103d5576103d5610370565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561040457610404610370565b60405281815282820160200187101561041b575f5ffd5b816020840160208301375f6020928201830152969401359450505050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156103535761035361044d565b5f600182016104855761048561044d565b5060010190565b600181811c908216806104a057607f821691505b6020821081036104be57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561050b57805f5260205f20601f840160051c810160208510156104e95750805b601f840160051c820191505b81811015610508575f81556001016104f5565b50505b505050565b815167ffffffffffffffff81111561052a5761052a610370565b61053e81610538845461048c565b846104c4565b6020601f821160018114610570575f83156105595750848201515b5f19600385901b1c1916600184901b178455610508565b5f84815260208120601f198516915b8281101561059f578785015182556020948501946001909201910161057f565b50848210156105bc57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b604081525f83518060408401528060208601606085015e5f606082850101526060601f19601f830116840101915050826020830152939250505056fea2646970667358221220fc626fb4c4a714a7a21320edb6a367116b08ea121e1795f526bf42d230f8682e64736f6c634300081c0033",
"deployedBytecode": "0x608060405234801561000f575f5ffd5b5060043610610034575f3560e01c80632a8fb18a14610038578063ece28c6c1461004d575b5f5ffd5b61004b610046366004610359565b610072565b005b61006061005b366004610384565b6101b6565b60405190815260200160405180910390f35b5f8111801561008257505f548111155b6100c05760405162461bcd60e51b815260206004820152600a6024820152691a5b9d985b1a59081a5960b21b60448201526064015b60405180910390fd5b5f8181526001602052604081209060038083015460ff16908111156100e7576100e7610439565b146101225760405162461bcd60e51b815260206004820152600b60248201526a4e6f742070656e64696e6760a81b60448201526064016100b7565b60018101546001600160a01b031633146101745760405162461bcd60e51b81526020600482015260136024820152723ab730baba3437b934bd32b21021b0b63632b960691b60448201526064016100b7565b8060040154421115610195576003818101805460ff191690911790556101a5565b60038101805460ff191660011790555b600301805460ff1916600117905550565b5f5f8351116101f45760405162461bcd60e51b815260206004820152600a602482015269115b5c1d1e481d195e1d60b21b60448201526064016100b7565b61020042610258610461565b82116102415760405162461bcd60e51b815260206004820152601060248201526f496e76616c696420646561646c696e6560801b60448201526064016100b7565b5f8054908061024f83610474565b90915550506040805160a0810182525f80548252336020830152918101859052906060820190815260209081018490525f805481526001808352604091829020845181559284015190830180546001600160a01b0319166001600160a01b0390921691909117905582015160028201906102c99082610510565b506060820151816003015f6101000a81548160ff021916908360038111156102f3576102f3610439565b0217905550608082015181600401559050507f022c3fffe570decf2328dbf4f2af598df5112da7e31568af8b927c48276ccae383836040516103369291906105cb565b60405180910390a15f8054908061034c83610474565b9190505590505b92915050565b5f60208284031215610369575f5ffd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215610395575f5ffd5b823567ffffffffffffffff8111156103ab575f5ffd5b8301601f810185136103bb575f5ffd5b803567ffffffffffffffff8111156103d5576103d5610370565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561040457610404610370565b60405281815282820160200187101561041b575f5ffd5b816020840160208301375f6020928201830152969401359450505050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b808201808211156103535761035361044d565b5f600182016104855761048561044d565b5060010190565b600181811c908216806104a057607f821691505b6020821081036104be57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561050b57805f5260205f20601f840160051c810160208510156104e95750805b601f840160051c820191505b81811015610508575f81556001016104f5565b50505b505050565b815167ffffffffffffffff81111561052a5761052a610370565b61053e81610538845461048c565b846104c4565b6020601f821160018114610570575f83156105595750848201515b5f19600385901b1c1916600184901b178455610508565b5f84815260208120601f198516915b8281101561059f578785015182556020948501946001909201910161057f565b50848210156105bc57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b604081525f83518060408401528060208601606085015e5f606082850101526060601f19601f830116840101915050826020830152939250505056fea2646970667358221220fc626fb4c4a714a7a21320edb6a367116b08ea121e1795f526bf42d230f8682e64736f6c634300081c0033",
"linkReferences": {},
"deployedLinkReferences": {},
"immutableReferences": {},
"inputSourceName": "project/contracts/todo.sol",
"buildInfoId": "solc-0_8_28-1dea80971854511ce292a51db1c18c65102b4187"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"_format": "hh3-sol-build-info-1",
"id": "solc-0_8_28-1dea80971854511ce292a51db1c18c65102b4187",
"solcVersion": "0.8.28",
"solcLongVersion": "0.8.28+commit.7893614a",
"userSourceNameMap": {
"contracts/todo.sol": "project/contracts/todo.sol"
},
"input": {
"language": "Solidity",
"settings": {
"evmVersion": "cancun",
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"": [
"ast"
],
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata"
]
}
},
"remappings": []
},
"sources": {
"project/contracts/todo.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n\ncontract Todo{\n uint256 todoCounter;\n\n enum Status {\n Pending,\n Done,\n Cancelled,\n Defaulted\n }\n\n\n struct TodoList{\n uint id;\n address owner;\n string text;\n Status status;\n uint256 deadline;\n }\n\n\n mapping(uint => TodoList) todos;\n event TodoCreated(string text, uint deadline);\n\n\n\n function createTodo(string memory _text, uint _deadline) external returns (uint) {\n require(bytes(_text).length > 0, \"Empty text\");\n require(_deadline > (block.timestamp + 600), \"Invalid deadline\");\n\n todoCounter++;\n\n todos[todoCounter] = TodoList(todoCounter, msg.sender, _text, Status.Pending, _deadline);\n\n\n emit TodoCreated(_text, _deadline);\n return todoCounter++;\n }\n\n\n function UpdateTodo(uint _id) external {\n require((_id > 0) && (_id <= todoCounter), 'invalid id');\n TodoList storage todo = todos[_id];\n require(todo.status == Status.Pending, \"Not pending\");\n require(msg.sender == todo.owner, \"unauthorized Caller\");\n\n\n if(block.timestamp > todo.deadline){\n todo.status = Status.Defaulted;\n }\n else {\n todo.status = Status.Done;\n }\n\n\n todo.status = Status.Done;\n }\n\n}\n"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"TodoModule#Todo": "0x745B93beda47F982a856D54a435C161A732a2B5A"
}
Loading