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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/openzeppelin/openzeppelin-contracts
4 changes: 4 additions & 0 deletions ASSIGNMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
== Return ==
0: contract AccessToken 0xBe7AbfF52fa56d8649DA14420B2f654102706447
1: contract MembershipNFT 0xA77bFE3E9CaF800f50eAa127F0049861fc316b0E
2: contract MembershipManager 0xD136CbD359aDB48Fd0eF4721EE7D028ddd916144
148 changes: 148 additions & 0 deletions broadcast/MembershipManager.s.sol/11155111/run-1754663773.json

Large diffs are not rendered by default.

148 changes: 148 additions & 0 deletions broadcast/MembershipManager.s.sol/11155111/run-latest.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/openzeppelin-contracts
Submodule openzeppelin-contracts added at c64a1e
20 changes: 20 additions & 0 deletions script/MembershipManager.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

import {Script} from "forge-std/Script.sol";
import {AccessToken} from "../src/AccessToken.sol";
import {MembershipNFT} from "../src/MembershipNFT.sol";
import {MembershipManager} from "../src/MembershipManager.sol";

contract deployContracts is Script {
function run() external returns(AccessToken, MembershipNFT, MembershipManager) {
vm.startBroadcast();
AccessToken accessToken = new AccessToken();
MembershipNFT membershipNFT = new MembershipNFT();
MembershipManager membershipManager = new MembershipManager(address(accessToken), address(membershipNFT), accessToken.getOwner());
vm.stopBroadcast();

return (accessToken, membershipNFT, membershipManager);
}
}
27 changes: 27 additions & 0 deletions src/AccessToken.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

import {ERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
contract AccessToken is ERC20{

address private owner;

modifier onlyOwner {
require(msg.sender == owner, "AccessToken:: Unauthorized User");
_;
}

constructor() ERC20("Access Token", "ACT"){
owner = msg.sender;
_mint(msg.sender, 1000000);
}

function mint(address to, uint256 _amount) onlyOwner external {
_mint(to, _amount);
}

function getOwner() external view returns(address) {
return owner;
}
}
276 changes: 138 additions & 138 deletions src/ERC20.sol
Original file line number Diff line number Diff line change
@@ -1,138 +1,138 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}

contract ERC20 is IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);

struct X {
uint256 x;
uint256 y;
}

// Experimental
event DummyEvent(X indexed structA, X structB);

uint256 public totalSupply;

mapping(address account => uint256 balance) public balanceOf;
mapping(address owner => mapping(address spender => uint256 amount))
public allowance;

string public name;
string public symbol;
uint8 public decimals;
address public adminAddress;

error InsufficientFundsError();
error UnauthorizedError();

constructor(
string memory _name,
string memory _symbol,
uint8 _decimals,
address _adminAddress
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
adminAddress = _adminAddress;
}

function transfer(
address recipient,
uint256 amount
) external returns (bool) {
// Verify that caller is not from address(0)
require(msg.sender != address(0), "Invalid caller");

// Verify that caller has enough tokens to send
// require(balanceOf[msg.sender] >= amount, "Insufficient funds");
if (balanceOf[msg.sender] < amount) {
revert InsufficientFundsError();
}

balanceOf[msg.sender] = balanceOf[msg.sender] - amount;
balanceOf[recipient] += amount;

emit Transfer(msg.sender, recipient, amount);
return true;
}

// Experimental
function emitDummyEvent() public {
X memory x;
x.x = 1;
x.y = 2;

emit DummyEvent(x, x);
}

function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);

return true;
}

function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool) {
allowance[from][msg.sender] -= amount;
balanceOf[from] -= amount;
balanceOf[to] += amount;

emit Transfer(from, to, amount);
return true;
}

function _mint(address to, uint256 amount) internal {
balanceOf[to] += amount;
totalSupply += amount;

emit Transfer(address(0), to, amount);
}

function _burn(address from, uint256 amount) internal {
balanceOf[from] -= amount;
totalSupply -= amount;

emit Transfer(from, address(0), amount);
}

function mint(address to, uint256 amount) external {
require(msg.sender == adminAddress, "Unauthorized");
_mint(to, amount);
}

function burn(address from, uint256 amount) external {
require(balanceOf[from] >= amount, "Insufficient funds");
_burn(from, amount);
}
}
// // SPDX-License-Identifier: MIT

// pragma solidity ^0.8.0;

// interface IERC20 {
// function totalSupply() external view returns (uint256);
// function balanceOf(address account) external view returns (uint256);
// function transfer(
// address recipient,
// uint256 amount
// ) external returns (bool);
// function allowance(
// address owner,
// address spender
// ) external view returns (uint256);
// function approve(address spender, uint256 amount) external returns (bool);
// function transferFrom(
// address from,
// address to,
// uint256 amount
// ) external returns (bool);
// }

// contract ERC20 is IERC20 {
// event Transfer(address indexed from, address indexed to, uint256 value);
// event Approval(
// address indexed owner,
// address indexed spender,
// uint256 value
// );

// struct X {
// uint256 x;
// uint256 y;
// }

// // Experimental
// event DummyEvent(X indexed structA, X structB);

// uint256 public totalSupply;

// mapping(address account => uint256 balance) public balanceOf;
// mapping(address owner => mapping(address spender => uint256 amount))
// public allowance;

// string public name;
// string public symbol;
// uint8 public decimals;
// address public adminAddress;

// error InsufficientFundsError();
// error UnauthorizedError();

// constructor(
// string memory _name,
// string memory _symbol,
// uint8 _decimals,
// address _adminAddress
// ) {
// name = _name;
// symbol = _symbol;
// decimals = _decimals;
// adminAddress = _adminAddress;
// }

// function transfer(
// address recipient,
// uint256 amount
// ) external returns (bool) {
// // Verify that caller is not from address(0)
// require(msg.sender != address(0), "Invalid caller");

// // Verify that caller has enough tokens to send
// // require(balanceOf[msg.sender] >= amount, "Insufficient funds");
// if (balanceOf[msg.sender] < amount) {
// revert InsufficientFundsError();
// }

// balanceOf[msg.sender] = balanceOf[msg.sender] - amount;
// balanceOf[recipient] += amount;

// emit Transfer(msg.sender, recipient, amount);
// return true;
// }

// // Experimental
// function emitDummyEvent() public {
// X memory x;
// x.x = 1;
// x.y = 2;

// emit DummyEvent(x, x);
// }

// function approve(address spender, uint256 amount) external returns (bool) {
// allowance[msg.sender][spender] = amount;
// emit Approval(msg.sender, spender, amount);

// return true;
// }

// function transferFrom(
// address from,
// address to,
// uint256 amount
// ) external returns (bool) {
// allowance[from][msg.sender] -= amount;
// balanceOf[from] -= amount;
// balanceOf[to] += amount;

// emit Transfer(from, to, amount);
// return true;
// }

// function _mint(address to, uint256 amount) internal {
// balanceOf[to] += amount;
// totalSupply += amount;

// emit Transfer(address(0), to, amount);
// }

// function _burn(address from, uint256 amount) internal {
// balanceOf[from] -= amount;
// totalSupply -= amount;

// emit Transfer(from, address(0), amount);
// }

// function mint(address to, uint256 amount) external {
// require(msg.sender == adminAddress, "Unauthorized");
// _mint(to, amount);
// }

// function burn(address from, uint256 amount) external {
// require(balanceOf[from] >= amount, "Insufficient funds");
// _burn(from, amount);
// }
// }
Loading