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/Solidity/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
190 changes: 190 additions & 0 deletions assignments/Solidity/Todo/contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Todo Smart Contract

A Solidity smart contract for managing todo items on the Ethereum blockchain.

## Overview

The Todo contract allows users to create todo items with deadlines, track their status, and mark them as done. The contract automatically handles deadline enforcement - if a todo is marked as done after its deadline, it will be marked as "Cancelled" instead of "Done".

## Contract Details

- **Solidity Version**: ^0.8.28
- **License**: UNLICENSED

## Contract Structure

### Data Structures

#### TodoList Struct
```solidity
struct TodoList {
uint256 id;
address owner;
string text;
Status status;
uint256 deadline;
}
```

#### Status Enum
```solidity
enum Status {
Pending,
Done,
Cancelled,
Defaulted
}
```

### State Variables

| Variable | Type | Description |
|----------|------|-------------|
| `todoCounter` | `uint256` | Auto-incrementing counter for todo IDs |
| `todos` | `mapping(uint => TodoList)` | Storage mapping for all todos |

### Events

- **`TodoCreated(string text, uint deadline)`** - Emitted when a new todo is created

## Functions

### createTodo

Creates a new todo item with a specified text and deadline.

```solidity
function createTodo(string memory _text, uint deadline) external returns(uint)
```

**Parameters:**
- `_text` - The todo description (cannot be empty)
- `deadline` - Unix timestamp (must be at least 10 minutes in the future)

**Returns:**
- `uint` - The ID of the newly created todo

**Requirements:**
- Text must not be empty
- Deadline must be at least 600 seconds (10 minutes) from current block timestamp

**Validation Error Messages:**
- `"Empty text"` - If text is empty
- `"Invalid deadline"` - If deadline is not at least 10 minutes in the future

---

### markAsDone

Marks a todo as done. Automatically checks if the deadline has passed.

```solidity
function markAsDone(uint _id) external
```

**Parameters:**
- `_id` - The ID of the todo to mark as done

**Requirements:**
- Todo ID must be valid (between 1 and todoCounter)
- Todo must be in "Pending" status

**Behavior:**
- If current timestamp > deadline: status becomes `Cancelled`
- If current timestamp <= deadline: status becomes `Done`

**Validation Error Messages:**
- `"Invalid id"` - If todo ID is out of bounds
- `"Not pending"` - If todo is not in Pending status

---

### todoCounter (Getter)

Returns the total number of todos created.

```solidity
function todoCounter() external view returns(uint256)
```

## Usage Example

### Creating a Todo

```javascript
// Create a todo with 1 hour deadline
const deadline = Math.floor(Date.now() / 1000) + 3600;
const tx = await todoContract.createTodo("Complete project report", deadline);
const receipt = await tx.wait();

// Get the todo ID from the event
const event = receipt.events.find(e => e.event === "TodoCreated");
const todoId = event.args[1]; // or use the return value from the function
```

### Marking a Todo as Done

```javascript
// Mark todo #1 as done
await todoContract.markAsDone(1);
```

### Reading Todo Data

```javascript
// Get the current todo counter
const count = await todoContract.todoCounter();

// Get a specific todo
const todo = await todoContract.todos(1);
console.log(todo.text);
console.log(todo.status); // 0=Pending, 1=Done, 2=Cancelled, 3=Defaulted
console.log(todo.deadline);
```

## Deployment

This project uses Hardhat for development and deployment.

### Install Dependencies

```bash
npm install
```

### Compile Contracts

```bash
npx hardhat compile
```

### Run Tests

```bash
npx hardhat test
```

### Deploy to Sepolia Testnet

```bash
npx hardhat ignition deploy ignition/modules/todo.ts --network sepolia
```

## Contract Address

After deployment, the contract address will be stored in:
```
ignition/deployments/chain-11155111/deployed_addresses.json
```

(Note: 11155111 is the chain ID for Sepolia testnet)

## Security Considerations

1. **Deadline Validation**: The contract requires a minimum 10-minute deadline to prevent front-running issues
2. **Access Control**: Only the todo owner can mark their todos as done (current implementation allows anyone to call markAsDone - consider adding owner validation for production use)
3. **Gas Efficiency**: The contract uses mappings for O(1) access to todo items

## License

UNLICENSED
78 changes: 78 additions & 0 deletions assignments/Solidity/Todo/contracts/Todo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.28;

contract Add{
function add(uint a, uint b) public pure returns(uint) {
uint c = a + b;
return c;
}
}

contract Average is Add {
function avergae(uint a, uint b) public pure returns(uint) {

}
}















contract Todo {
uint256 public todoCounter;

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

enum Status{
Pending,
Done,
Cancelled,
Defaulted
}

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 markAsDone(uint _id) external {
require((_id > 0) && (_id <= todoCounter), "Invalid id");
TodoList memory todo = todos[_id];
require((todo.status == Status.Pending), "Not pending");

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

todos[_id] = todo;
}
}
46 changes: 46 additions & 0 deletions assignments/Solidity/Todo/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import dotenv from "dotenv";
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"),
},
},
});
Loading