
Testnet by Morpho Labs
Morpho is a peer-to-peer layer built on top of lending pools such as Compound and Aave Raised: $18M from a16z crypto and 82 other investors Rewards: 51% of $MORPHO tokens are allocated to the communityOfficial announcement of the testnet launch Morpho 🦋 @MorphoLabs We have some exciting news! Morpho Blue and MetaMorpho contracts are deployed on Goerli Testnet! How can users and developers participate? 91 9:59 AM • Nov 15, 2023 What to do? • Request test tokens from the faucet• Visit the webs...

Antimatter testnet guide
Antimatter is a BNB Chain Sidechain for the scalability of financial infrastructure 💰 Rewards: possible airdrop 📣 Official announcement: link The last testnet before the launch of the mainnet is running nowWhat to do?Manually add a test network to MetaMask Name: Antimatter B2 Testnet RPC URL: http://bastest-rpc.antimatter.finance Chain ID: 20221 Currency Symbol: MATTER Explorer: http://bastest-explorer.antimatter.financeNext, take the test tokens from the faucetNow go to the website and con...

GMX V2 Testnet with possible airdrop
GMX is a decentralised perpetual exchange ⏱ Time to complete: ~10 min 📣 Yesterday, the project announced the launch of the public V2 TestnetWhat to do?Go to the website and add the Avalanche Fuji Testnet network to your MetaMask by clicking "Add Subnet to Metamask"Get test tokens on the same websiteVisit the website and connect your walletSwitch to the "Buy" tab and buy $GM tokensGo to the "Trade" tab and open several different positions (Long/Short, Market/Limit)Also, swap available tokens ...
Exploring the crypto market under the microscope 🔬

Testnet by Morpho Labs
Morpho is a peer-to-peer layer built on top of lending pools such as Compound and Aave Raised: $18M from a16z crypto and 82 other investors Rewards: 51% of $MORPHO tokens are allocated to the communityOfficial announcement of the testnet launch Morpho 🦋 @MorphoLabs We have some exciting news! Morpho Blue and MetaMorpho contracts are deployed on Goerli Testnet! How can users and developers participate? 91 9:59 AM • Nov 15, 2023 What to do? • Request test tokens from the faucet• Visit the webs...

Antimatter testnet guide
Antimatter is a BNB Chain Sidechain for the scalability of financial infrastructure 💰 Rewards: possible airdrop 📣 Official announcement: link The last testnet before the launch of the mainnet is running nowWhat to do?Manually add a test network to MetaMask Name: Antimatter B2 Testnet RPC URL: http://bastest-rpc.antimatter.finance Chain ID: 20221 Currency Symbol: MATTER Explorer: http://bastest-explorer.antimatter.financeNext, take the test tokens from the faucetNow go to the website and con...

GMX V2 Testnet with possible airdrop
GMX is a decentralised perpetual exchange ⏱ Time to complete: ~10 min 📣 Yesterday, the project announced the launch of the public V2 TestnetWhat to do?Go to the website and add the Avalanche Fuji Testnet network to your MetaMask by clicking "Add Subnet to Metamask"Get test tokens on the same websiteVisit the website and connect your walletSwitch to the "Buy" tab and buy $GM tokensGo to the "Trade" tab and open several different positions (Long/Short, Market/Limit)Also, swap available tokens ...
Exploring the crypto market under the microscope 🔬

Subscribe to Atoms Research

Subscribe to Atoms Research
Share Dialog
Share Dialog
>600 subscribers
>600 subscribers


Base is an Ethereum L2, incubated by Coinbase and built on the open-source OP Stack
Coinbase raised $574.2M from a16z, Polychain Capital, and others
• Add the testnet network to your wallet

• Request test tokens from the faucet

• Go to Remix and create a new workspace
• Visit the “Solidity Compiler” tab
• Select version 0.8.0 and click “Auto Compile”
• Open the “Deploy Transactions” tab
• Select MetaMask as Environment
• Create a new file and paste this code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BasicMath {
function adder(uint _a, uint _b) external pure returns (uint sum, bool error) {
unchecked {
uint result = _a + _b;
if (result >= _a && result >= _b) {
return (result, false);
} else {
return (0, true);
}
}
}
function subtractor(uint _a, uint _b) external pure returns (uint difference, bool error) {
unchecked {
if (_b <= _a) {
return (_a - _b, false);
} else {
return (0, true);
}
}
}
}
• Deploy the contract and verify the transaction here
• Create a new file again and paste this code:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
contract ControlStructures {
error AfterHours(uint256 time);
error AtLunch();
function fizzBuzz(uint256 _number) public pure returns (string memory response) {
if (_number % 3 == 0 && _number % 5 == 0) {
return "FizzBuzz";
} else if (_number % 3 == 0) {
return "Fizz";
} else if (_number % 5 == 0) {
return "Buzz";
} else {
return "Splat";
}
}
function doNotDisturb(uint256 _time) public pure returns (string memory result) {
assert(_time < 2400);
if (_time > 2200 || _time < 800) {
revert AfterHours(_time);
} else if (_time >= 1200 && _time <= 1299) {
revert("At lunch!");
} else if (_time >= 800 && _time <= 1199) {
return "Morning!";
} else if (_time >= 1300 && _time <= 1799) {
return "Afternoon!";
} else if (_time >= 1800 && _time <= 2200) {
return "Evening!";
}
}
}
• Deploy the contract and verify the transaction here
• Do the same with the following codes
• Code (3):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract EmployeeStorage {
uint16 private shares;
uint32 private salary;
uint256 public idNumber;
string public name;
constructor(uint16 _shares, string memory _name, uint32 _salary, uint _idNumber) {
shares = _shares;
name = _name;
salary = _salary;
idNumber = _idNumber;
}
function viewShares() public view returns (uint16) {
return shares;
}
function viewSalary() public view returns (uint32) {
return salary;
}
error TooManyShares(uint16 _shares);
function grantShares(uint16 _newShares) public {
if (_newShares > 5000) {
revert("Too many shares");
} else if (shares + _newShares > 5000) {
revert TooManyShares(shares + _newShares);
}
shares += _newShares;
}
/**
* Do not modify this function. It is used to enable the unit test for this pin
* to check whether or not you have configured your storage variables to make
* use of packing.
*
* If you wish to cheat, simply modify this function to always return `0`
* I'm not your boss ¯\_(ツ)_/¯
*
* Fair warning though, if you do cheat, it will be on the blockchain having been
* deployed by you wallet....FOREVER!
*/
function checkForPacking(uint _slot) public view returns (uint r) {
assembly {
r := sload (_slot)
}
}
/**
* Warning: Anyone can use this function at any time!
*/
function debugResetShares() public {
shares = 1000;
}
}
• Verify
• Code (4):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract ArraysExercise {
uint[] numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
uint[] timestamps;
address[] senders;
uint256 constant Y2K = 946702800;
function getNumbers() external view returns (uint[] memory) {
uint[] memory results = new uintUnsupported embed;
for(uint i=0; i<numbers.length; i++) {
results[i] = numbers[i];
}
return results;
}
function resetNumbers() public {
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}
function appendToNumbers(uint[] calldata _toAppend) public {
uint _counter = _toAppend.length;
for (uint i; i < _counter; i++) {
numbers.push(_toAppend[i]);
}
}
function saveTimestamp(uint _unixTimestamp) public {
timestamps.push(_unixTimestamp);
senders.push(msg.sender);
}
function afterY2K() public view returns (uint256[] memory, address[] memory) {
uint256 counter = 0;
for (uint i = 0; i < timestamps.length; i++) {
if (timestamps[i] > Y2K) {
counter++;
}
}
uint256[] memory timestampsAfterY2K = new uint256Unsupported embed;
address[] memory sendersAfterY2K = new addressUnsupported embed;
uint256 index = 0;
for (uint i = 0; i < timestamps.length; i++) {
if (timestamps[i] > Y2K) {
timestampsAfterY2K[index] = timestamps[i];
sendersAfterY2K[index] = senders[i];
index++;
}
}
return (timestampsAfterY2K, sendersAfterY2K);
}
function resetSenders() public {
delete senders;
}
function resetTimestamps() public {
delete timestamps;
}
}
• Verify
• Code (5):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/**
* @title FavoriteRecords
* @dev Contract to manage a list of approved music records and allow users to add them to their favorites
*/
contract FavoriteRecords {
mapping(string => bool) private approvedRecords;
string[] private approvedRecordsIndex;
mapping(address => mapping(string => bool)) public userFavorites;
mapping(address => string[]) private userFavoritesIndex;
error NotApproved(string albumName);
/**
* @dev Constructor that initializes the approved records list
*/
constructor() {
approvedRecordsIndex = ["Thriller","Back in Black","The Bodyguard","The Dark Side of the Moon","Their Greatest Hits (1971-1975)","Hotel California","Come On Over","Rumours","Saturday Night Fever"];
for (uint i = 0; i < approvedRecordsIndex.length; i++)
{
approvedRecords[approvedRecordsIndex[i]] = true;
}
}
/**
* @dev Returns the list of approved records
* @return An array of approved record names
*/
function getApprovedRecords() public view returns (string[] memory) {
return approvedRecordsIndex;
}
/**
* @dev Adds an approved record to the user's favorites
* @param _albumName The name of the album to be added
*/
function addRecord(string memory _albumName) public {
if (!approvedRecords[_albumName]) {
revert NotApproved({albumName: _albumName});
}
if (!userFavorites[msg.sender][_albumName]) {
userFavorites[msg.sender][_albumName] = true;
userFavoritesIndex[msg.sender].push(_albumName);
}
}
/**
* @dev Returns the list of a user's favorite records
* @param _address The address of the user
* @return An array of user's favorite record names
*/
function getUserFavorites(address _address) public view returns (string[] memory) {
return userFavoritesIndex[_address];
}
/**
* @dev Resets the caller's list of favorite records
*/
function resetUserFavorites() public {
for (uint i = 0; i < userFavoritesIndex[msg.sender].length; i++) {
delete userFavorites[msg.sender][userFavoritesIndex[msg.sender][i]];
}
delete userFavoritesIndex[msg.sender];
}
}
• Verify
• Code (6):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/**
* @title GarageManager
* @dev Contract to manage a garage of cars for each user
*/
contract GarageManager {
mapping(address => Car[]) private garages;
struct Car {
string make;
string model;
string color;
uint numberOfDoors;
}
error BadCarIndex(uint256 index);
/**
* @dev Adds a new car to the caller's garage
* @param _make The make of the car
* @param _model The model of the car
* @param _color The color of the car
* @param _numberOfDoors The number of doors of the car
*/
function addCar(string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
garages[msg.sender].push(Car(_make, _model, _color, _numberOfDoors));
}
/**
* @dev Retrieves the caller's array of cars
* @return An array of `Car` structs
*/
function getMyCars() external view returns (Car[] memory) {
return garages[msg.sender];
}
/**
* @dev Retrieves a specific user's array of cars
* @param _user The address of the user
* @return An array of `Car` structs
*/
function getUserCars(address _user) external view returns (Car[] memory) {
return garages[_user];
}
/**
* @dev Updates a specific car in the caller's garage
* @param _index The index of the car in the garage array
* @param _make The new make of the car
* @param _model The new model of the car
* @param _color The new color of the car
* @param _numberOfDoors The new number of doors of the car
*/
function updateCar(uint256 _index, string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
if (_index >= garages[msg.sender].length) {
revert BadCarIndex({index: _index});
}
garages[msg.sender][_index] = Car(_make, _model, _color, _numberOfDoors);
}
/**
* @dev Deletes all cars in the caller's garage
*/
function resetMyGarage() external {
delete garages[msg.sender];
}
}
• Verify
• Code (7):
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
abstract contract Employee
{
uint public idNumber;
uint public managerId;
constructor(uint _idNumber, uint _managerId)
{
idNumber = _idNumber;
managerId = _managerId;
}
function getAnnualCost() public virtual returns (uint);
}
contract Salaried is Employee
{
uint public annualSalary;
constructor(uint _idNumber, uint _managerId, uint _annualSalary)
Employee(_idNumber, _managerId)
{
annualSalary = _annualSalary;
}
function getAnnualCost() public override view returns (uint)
{
return annualSalary;
}
}
contract Hourly is Employee
{
uint public hourlyRate;
constructor(uint _idNumber, uint _managerId, uint _hourlyRate) Employee(_idNumber, _managerId)
{
hourlyRate = _hourlyRate;
}
function getAnnualCost() public override view returns (uint)
{
return hourlyRate * 2080;
}
}
contract Manager
{
uint[] public employeeIds;
function addReport(uint _reportId) public
{
employeeIds.push(_reportId);
}
function resetReports() public
{
delete employeeIds;
}
}
contract Salesperson is Hourly
{
constructor(uint _idNumber, uint _managerId, uint _hourlyRate)
Hourly(_idNumber, _managerId, _hourlyRate) {}
}
contract EngineeringManager is Salaried, Manager
{
constructor(uint _idNumber, uint _managerId, uint _annualSalary)
Salaried(_idNumber, _managerId, _annualSalary) {}
}
contract InheritanceSubmission {
address public salesPerson;
address public engineeringManager;
constructor(address _salesPerson, address _engineeringManager) {
salesPerson = _salesPerson;
engineeringManager = _engineeringManager;
}
}
• On the “Deploy” tab select the same as in the first screenshot
• Click “Transact” and save the contract address
• Now do the same as indicated in the second screenshot

• Press “Transact” again and save the contract address
• Change the contract again and enter the addresses you copied earlier and press “Transact”

• Paste the contract address and confirm the transaction here
• Next, you need to create two new files: Imports and SillyStringUtils
• Paste a code (8):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract ErrorTriageExercise {
/**
* Finds the difference between each uint with it's neighbor (a to b, b to c, etc.)
* and returns a uint array with the absolute integer difference of each pairing.
*/
function diffWithNeighbor(
uint _a,
uint _b,
uint _c,
uint _d
) public pure returns (uint[] memory) {
uint[] memory results = new uintUnsupported embed;
results[0] = _a > _b ? _a - _b : _b - _a;
results[1] = _b > _c ? _b - _c : _c - _b;
results[2] = _c > _d ? _c - _d : _d - _c;
return results;
}
/**
* Changes the _base by the value of _modifier. Base is always >= 1000. Modifiers can be
* between positive and negative 100;
*/
function applyModifier(
uint _base,
int _modifier
) public pure returns (uint returnValue) {
if(_modifier > 0) {
return _base + uint(_modifier);
}
return _base - uint(-_modifier);
}
/**
* Pop the last element from the supplied array, and return the popped
* value (unlike the built-in function)
*/
uint[] arr;
function popWithReturn() public returns (uint returnNum) {
if(arr.length > 0) {
uint result = arr[arr.length - 1];
arr.pop();
return result;
}
}
// The utility functions below are working as expected
function addToArr(uint _num) public {
arr.push(_num);
}
function getArr() public view returns (uint[] memory) {
return arr;
}
function resetArr() public {
delete arr;
}
}
• Verify
• Code (9):
AddressBook.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@openzeppelin/contracts/access/Ownable.sol";
contract AddressBook is Ownable(msg.sender) {
string private salt = "value";
struct Contact {
uint id;
string firstName;
string lastName;
uint[] phoneNumbers;
}
Contact[] private contacts;
mapping(uint => uint) private idToIndex;
uint private nextId = 1;
error ContactNotFound(uint id);
function addContact(string calldata firstName, string calldata lastName, uint[] calldata phoneNumbers) external onlyOwner {
contacts.push(Contact(nextId, firstName, lastName, phoneNumbers));
idToIndex[nextId] = contacts.length - 1;
nextId++;
}
function deleteContact(uint id) external onlyOwner {
uint index = idToIndex[id];
if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
contacts[index] = contacts[contacts.length - 1];
idToIndex[contacts[index].id] = index;
contacts.pop();
delete idToIndex[id];
}
function getContact(uint id) external view returns (Contact memory) {
uint index = idToIndex[id];
if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
return contacts[index];
}
function getAllContacts() external view returns (Contact[] memory) {
return contacts;
}
}
Other contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./AddressBook.sol";
contract AddressBookFactory {
string private salt = "value";
function deploy() external returns (AddressBook) {
AddressBook newAddressBook = new AddressBook();
newAddressBook.transferOwnership(msg.sender);
return newAddressBook;
}
}
• Code (9.1):
• Create another file and paste the second part of the code
• In the 4th field, enter the name of the file that you created before
• Copy and deploy the last file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./9.sol";
contract AddressBookFactory {
string private salt = "value";
function deploy() external returns (AddressBook) {
AddressBook newAddressBook = new AddressBook();
newAddressBook.transferOwnership(msg.sender);
return newAddressBook;
}
}
• Verify
• Code (10):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract UnburnableToken {
string private salt = "value";
mapping(address => uint256) public balances;
uint256 public totalSupply;
uint256 public totalClaimed;
mapping(address => bool) private claimed;
// Custom errors
error TokensClaimed();
error AllTokensClaimed();
error UnsafeTransfer(address _to);
constructor() {
totalSupply = 100000000; // Set the total supply of tokens
}
// Public function to claim tokens
function claim() public {
if (totalClaimed >= totalSupply) revert AllTokensClaimed(); // Check if all tokens have been claimed
if (claimed[msg.sender]) revert TokensClaimed(); // Check if the caller has already claimed tokens
// Update balances and claimed status
balances[msg.sender] += 1000;
totalClaimed += 1000;
claimed[msg.sender] = true;
}
// Public function for safe token transfer
function safeTransfer(address _to, uint256 _amount) public {
// Check for unsafe transfer conditions, including if the target address has a non-zero ether balance
if (_to == address(0) || _to.balance == 0) revert UnsafeTransfer(_to);
// Ensure the sender has enough balance to transfer
require(balances[msg.sender] >= _amount, "Insufficient balance");
// Perform the transfer
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
• Verify
• Code (11):
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract WeightedVoting is ERC20 {
string private salt = "value";
using EnumerableSet for EnumerableSet.AddressSet;
error TokensClaimed();
error AllTokensClaimed();
error NoTokensHeld();
error QuorumTooHigh();
error AlreadyVoted();
error VotingClosed();
struct Issue {
EnumerableSet.AddressSet voters;
string issueDesc;
uint256 quorum;
uint256 totalVotes;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
bool passed;
bool closed;
}
struct SerializedIssue {
address[] voters;
string issueDesc;
uint256 quorum;
uint256 totalVotes;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
bool passed;
bool closed;
}
enum Vote {
AGAINST,
FOR,
ABSTAIN
}
Issue[] internal issues;
mapping(address => bool) public tokensClaimed;
uint256 public maxSupply = 1000000;
uint256 public claimAmount = 100;
string saltt = "any";
constructor(string memory _name, string memory _symbol)
ERC20(_name, _symbol)
{
issues.push();
}
function claim() public {
if (totalSupply() + claimAmount > maxSupply) {
revert AllTokensClaimed();
}
if (tokensClaimed[msg.sender]) {
revert TokensClaimed();
}
_mint(msg.sender, claimAmount);
tokensClaimed[msg.sender] = true;
}
function createIssue(string calldata _issueDesc, uint256 _quorum)
external
returns (uint256)
{
if (balanceOf(msg.sender) == 0) {
revert NoTokensHeld();
}
if (_quorum > totalSupply()) {
revert QuorumTooHigh();
}
Issue storage _issue = issues.push();
_issue.issueDesc = _issueDesc;
_issue.quorum = _quorum;
return issues.length - 1;
}
function getIssue(uint256 _issueId)
external
view
returns (SerializedIssue memory)
{
Issue storage _issue = issues[_issueId];
return
SerializedIssue({
voters: _issue.voters.values(),
issueDesc: _issue.issueDesc,
quorum: _issue.quorum,
totalVotes: _issue.totalVotes,
votesFor: _issue.votesFor,
votesAgainst: _issue.votesAgainst,
votesAbstain: _issue.votesAbstain,
passed: _issue.passed,
closed: _issue.closed
});
}
function vote(uint256 _issueId, Vote _vote) public {
Issue storage _issue = issues[_issueId];
if (_issue.closed) {
revert VotingClosed();
}
if (_issue.voters.contains(msg.sender)) {
revert AlreadyVoted();
}
uint256 nTokens = balanceOf(msg.sender);
if (nTokens == 0) {
revert NoTokensHeld();
}
if (_vote == Vote.AGAINST) {
_issue.votesAgainst += nTokens;
} else if (_vote == Vote.FOR) {
_issue.votesFor += nTokens;
} else {
_issue.votesAbstain += nTokens;
}
_issue.voters.add(msg.sender);
_issue.totalVotes += nTokens;
if (_issue.totalVotes >= _issue.quorum) {
_issue.closed = true;
if (_issue.votesFor > _issue.votesAgainst) {
_issue.passed = true;
}
}
}
}
• Verify
• Code (12):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
interface ISubmission {
struct Haiku {
address author;
string line1;
string line2;
string line3;
}
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external;
// function ownerOf(uint256 _id) external view returns (address);
function counter() external view returns (uint256);
function shareHaiku(uint256 _id, address _to) external;
function getMySharedHaikus() external view returns (Haiku[] memory);
}
contract HaikuNFT is ERC721, ISubmission {
Haiku[] public haikus;
mapping(address => mapping(uint256 => bool)) public sharedHaikus;
uint256 public haikuCounter;
constructor() ERC721("HaikuNFT", "HAIKU") {
haikuCounter = 1;
}
string salt = "value";
function counter() external view override returns (uint256) {
return haikuCounter;
}
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external override {
// Check if the haiku is unique
string[3] memory haikusStrings = [_line1, _line2, _line3];
for (uint256 li = 0; li < haikusStrings.length; li++) {
string memory newLine = haikusStrings[li];
// string memory newHaikuString = string(
// abi.encodePacked(haikusStrings[li])
// );
for (uint256 i = 0; i < haikus.length; i++) {
Haiku memory existingHaiku = haikus[i];
string[3] memory existingHaikuStrings = [
existingHaiku.line1,
existingHaiku.line2,
existingHaiku.line3
];
for (uint256 eHsi = 0; eHsi < 3; eHsi++) {
string memory existingHaikuString = existingHaikuStrings[
eHsi
];
if (
keccak256(abi.encodePacked(existingHaikuString)) ==
keccak256(abi.encodePacked(newLine))
) {
revert HaikuNotUnique();
}
}
}
}
// Mint the haiku NFT
_safeMint(msg.sender, haikuCounter);
haikus.push(Haiku(msg.sender, _line1, _line2, _line3));
haikuCounter++;
}
function shareHaiku(uint256 _id, address _to) external override {
require(_id > 0 && _id <= haikuCounter, "Invalid haiku ID");
Haiku memory haikuToShare = haikus[_id - 1];
require(haikuToShare.author == msg.sender, "NotYourHaiku");
sharedHaikus[_to][_id] = true;
}
function getMySharedHaikus()
external
view
override
returns (Haiku[] memory)
{
uint256 sharedHaikuCount;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
sharedHaikuCount++;
}
}
Haiku[] memory result = new HaikuUnsupported embed;
uint256 currentIndex;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
result[currentIndex] = haikus[i];
currentIndex++;
}
}
if (sharedHaikuCount == 0) {
revert NoHaikusShared();
}
return result;
}
error HaikuNotUnique();
error NotYourHaiku();
error NoHaikusShared();
}
• Verify
✅ That’s all!
✨ Collect this entry showing your support to our team! More collects-more guides!
Base is an Ethereum L2, incubated by Coinbase and built on the open-source OP Stack
Coinbase raised $574.2M from a16z, Polychain Capital, and others
• Add the testnet network to your wallet

• Request test tokens from the faucet

• Go to Remix and create a new workspace
• Visit the “Solidity Compiler” tab
• Select version 0.8.0 and click “Auto Compile”
• Open the “Deploy Transactions” tab
• Select MetaMask as Environment
• Create a new file and paste this code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract BasicMath {
function adder(uint _a, uint _b) external pure returns (uint sum, bool error) {
unchecked {
uint result = _a + _b;
if (result >= _a && result >= _b) {
return (result, false);
} else {
return (0, true);
}
}
}
function subtractor(uint _a, uint _b) external pure returns (uint difference, bool error) {
unchecked {
if (_b <= _a) {
return (_a - _b, false);
} else {
return (0, true);
}
}
}
}
• Deploy the contract and verify the transaction here
• Create a new file again and paste this code:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
contract ControlStructures {
error AfterHours(uint256 time);
error AtLunch();
function fizzBuzz(uint256 _number) public pure returns (string memory response) {
if (_number % 3 == 0 && _number % 5 == 0) {
return "FizzBuzz";
} else if (_number % 3 == 0) {
return "Fizz";
} else if (_number % 5 == 0) {
return "Buzz";
} else {
return "Splat";
}
}
function doNotDisturb(uint256 _time) public pure returns (string memory result) {
assert(_time < 2400);
if (_time > 2200 || _time < 800) {
revert AfterHours(_time);
} else if (_time >= 1200 && _time <= 1299) {
revert("At lunch!");
} else if (_time >= 800 && _time <= 1199) {
return "Morning!";
} else if (_time >= 1300 && _time <= 1799) {
return "Afternoon!";
} else if (_time >= 1800 && _time <= 2200) {
return "Evening!";
}
}
}
• Deploy the contract and verify the transaction here
• Do the same with the following codes
• Code (3):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract EmployeeStorage {
uint16 private shares;
uint32 private salary;
uint256 public idNumber;
string public name;
constructor(uint16 _shares, string memory _name, uint32 _salary, uint _idNumber) {
shares = _shares;
name = _name;
salary = _salary;
idNumber = _idNumber;
}
function viewShares() public view returns (uint16) {
return shares;
}
function viewSalary() public view returns (uint32) {
return salary;
}
error TooManyShares(uint16 _shares);
function grantShares(uint16 _newShares) public {
if (_newShares > 5000) {
revert("Too many shares");
} else if (shares + _newShares > 5000) {
revert TooManyShares(shares + _newShares);
}
shares += _newShares;
}
/**
* Do not modify this function. It is used to enable the unit test for this pin
* to check whether or not you have configured your storage variables to make
* use of packing.
*
* If you wish to cheat, simply modify this function to always return `0`
* I'm not your boss ¯\_(ツ)_/¯
*
* Fair warning though, if you do cheat, it will be on the blockchain having been
* deployed by you wallet....FOREVER!
*/
function checkForPacking(uint _slot) public view returns (uint r) {
assembly {
r := sload (_slot)
}
}
/**
* Warning: Anyone can use this function at any time!
*/
function debugResetShares() public {
shares = 1000;
}
}
• Verify
• Code (4):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract ArraysExercise {
uint[] numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
uint[] timestamps;
address[] senders;
uint256 constant Y2K = 946702800;
function getNumbers() external view returns (uint[] memory) {
uint[] memory results = new uintUnsupported embed;
for(uint i=0; i<numbers.length; i++) {
results[i] = numbers[i];
}
return results;
}
function resetNumbers() public {
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}
function appendToNumbers(uint[] calldata _toAppend) public {
uint _counter = _toAppend.length;
for (uint i; i < _counter; i++) {
numbers.push(_toAppend[i]);
}
}
function saveTimestamp(uint _unixTimestamp) public {
timestamps.push(_unixTimestamp);
senders.push(msg.sender);
}
function afterY2K() public view returns (uint256[] memory, address[] memory) {
uint256 counter = 0;
for (uint i = 0; i < timestamps.length; i++) {
if (timestamps[i] > Y2K) {
counter++;
}
}
uint256[] memory timestampsAfterY2K = new uint256Unsupported embed;
address[] memory sendersAfterY2K = new addressUnsupported embed;
uint256 index = 0;
for (uint i = 0; i < timestamps.length; i++) {
if (timestamps[i] > Y2K) {
timestampsAfterY2K[index] = timestamps[i];
sendersAfterY2K[index] = senders[i];
index++;
}
}
return (timestampsAfterY2K, sendersAfterY2K);
}
function resetSenders() public {
delete senders;
}
function resetTimestamps() public {
delete timestamps;
}
}
• Verify
• Code (5):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/**
* @title FavoriteRecords
* @dev Contract to manage a list of approved music records and allow users to add them to their favorites
*/
contract FavoriteRecords {
mapping(string => bool) private approvedRecords;
string[] private approvedRecordsIndex;
mapping(address => mapping(string => bool)) public userFavorites;
mapping(address => string[]) private userFavoritesIndex;
error NotApproved(string albumName);
/**
* @dev Constructor that initializes the approved records list
*/
constructor() {
approvedRecordsIndex = ["Thriller","Back in Black","The Bodyguard","The Dark Side of the Moon","Their Greatest Hits (1971-1975)","Hotel California","Come On Over","Rumours","Saturday Night Fever"];
for (uint i = 0; i < approvedRecordsIndex.length; i++)
{
approvedRecords[approvedRecordsIndex[i]] = true;
}
}
/**
* @dev Returns the list of approved records
* @return An array of approved record names
*/
function getApprovedRecords() public view returns (string[] memory) {
return approvedRecordsIndex;
}
/**
* @dev Adds an approved record to the user's favorites
* @param _albumName The name of the album to be added
*/
function addRecord(string memory _albumName) public {
if (!approvedRecords[_albumName]) {
revert NotApproved({albumName: _albumName});
}
if (!userFavorites[msg.sender][_albumName]) {
userFavorites[msg.sender][_albumName] = true;
userFavoritesIndex[msg.sender].push(_albumName);
}
}
/**
* @dev Returns the list of a user's favorite records
* @param _address The address of the user
* @return An array of user's favorite record names
*/
function getUserFavorites(address _address) public view returns (string[] memory) {
return userFavoritesIndex[_address];
}
/**
* @dev Resets the caller's list of favorite records
*/
function resetUserFavorites() public {
for (uint i = 0; i < userFavoritesIndex[msg.sender].length; i++) {
delete userFavorites[msg.sender][userFavoritesIndex[msg.sender][i]];
}
delete userFavoritesIndex[msg.sender];
}
}
• Verify
• Code (6):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
/**
* @title GarageManager
* @dev Contract to manage a garage of cars for each user
*/
contract GarageManager {
mapping(address => Car[]) private garages;
struct Car {
string make;
string model;
string color;
uint numberOfDoors;
}
error BadCarIndex(uint256 index);
/**
* @dev Adds a new car to the caller's garage
* @param _make The make of the car
* @param _model The model of the car
* @param _color The color of the car
* @param _numberOfDoors The number of doors of the car
*/
function addCar(string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
garages[msg.sender].push(Car(_make, _model, _color, _numberOfDoors));
}
/**
* @dev Retrieves the caller's array of cars
* @return An array of `Car` structs
*/
function getMyCars() external view returns (Car[] memory) {
return garages[msg.sender];
}
/**
* @dev Retrieves a specific user's array of cars
* @param _user The address of the user
* @return An array of `Car` structs
*/
function getUserCars(address _user) external view returns (Car[] memory) {
return garages[_user];
}
/**
* @dev Updates a specific car in the caller's garage
* @param _index The index of the car in the garage array
* @param _make The new make of the car
* @param _model The new model of the car
* @param _color The new color of the car
* @param _numberOfDoors The new number of doors of the car
*/
function updateCar(uint256 _index, string memory _make, string memory _model, string memory _color, uint _numberOfDoors) external {
if (_index >= garages[msg.sender].length) {
revert BadCarIndex({index: _index});
}
garages[msg.sender][_index] = Car(_make, _model, _color, _numberOfDoors);
}
/**
* @dev Deletes all cars in the caller's garage
*/
function resetMyGarage() external {
delete garages[msg.sender];
}
}
• Verify
• Code (7):
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
abstract contract Employee
{
uint public idNumber;
uint public managerId;
constructor(uint _idNumber, uint _managerId)
{
idNumber = _idNumber;
managerId = _managerId;
}
function getAnnualCost() public virtual returns (uint);
}
contract Salaried is Employee
{
uint public annualSalary;
constructor(uint _idNumber, uint _managerId, uint _annualSalary)
Employee(_idNumber, _managerId)
{
annualSalary = _annualSalary;
}
function getAnnualCost() public override view returns (uint)
{
return annualSalary;
}
}
contract Hourly is Employee
{
uint public hourlyRate;
constructor(uint _idNumber, uint _managerId, uint _hourlyRate) Employee(_idNumber, _managerId)
{
hourlyRate = _hourlyRate;
}
function getAnnualCost() public override view returns (uint)
{
return hourlyRate * 2080;
}
}
contract Manager
{
uint[] public employeeIds;
function addReport(uint _reportId) public
{
employeeIds.push(_reportId);
}
function resetReports() public
{
delete employeeIds;
}
}
contract Salesperson is Hourly
{
constructor(uint _idNumber, uint _managerId, uint _hourlyRate)
Hourly(_idNumber, _managerId, _hourlyRate) {}
}
contract EngineeringManager is Salaried, Manager
{
constructor(uint _idNumber, uint _managerId, uint _annualSalary)
Salaried(_idNumber, _managerId, _annualSalary) {}
}
contract InheritanceSubmission {
address public salesPerson;
address public engineeringManager;
constructor(address _salesPerson, address _engineeringManager) {
salesPerson = _salesPerson;
engineeringManager = _engineeringManager;
}
}
• On the “Deploy” tab select the same as in the first screenshot
• Click “Transact” and save the contract address
• Now do the same as indicated in the second screenshot

• Press “Transact” again and save the contract address
• Change the contract again and enter the addresses you copied earlier and press “Transact”

• Paste the contract address and confirm the transaction here
• Next, you need to create two new files: Imports and SillyStringUtils
• Paste a code (8):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract ErrorTriageExercise {
/**
* Finds the difference between each uint with it's neighbor (a to b, b to c, etc.)
* and returns a uint array with the absolute integer difference of each pairing.
*/
function diffWithNeighbor(
uint _a,
uint _b,
uint _c,
uint _d
) public pure returns (uint[] memory) {
uint[] memory results = new uintUnsupported embed;
results[0] = _a > _b ? _a - _b : _b - _a;
results[1] = _b > _c ? _b - _c : _c - _b;
results[2] = _c > _d ? _c - _d : _d - _c;
return results;
}
/**
* Changes the _base by the value of _modifier. Base is always >= 1000. Modifiers can be
* between positive and negative 100;
*/
function applyModifier(
uint _base,
int _modifier
) public pure returns (uint returnValue) {
if(_modifier > 0) {
return _base + uint(_modifier);
}
return _base - uint(-_modifier);
}
/**
* Pop the last element from the supplied array, and return the popped
* value (unlike the built-in function)
*/
uint[] arr;
function popWithReturn() public returns (uint returnNum) {
if(arr.length > 0) {
uint result = arr[arr.length - 1];
arr.pop();
return result;
}
}
// The utility functions below are working as expected
function addToArr(uint _num) public {
arr.push(_num);
}
function getArr() public view returns (uint[] memory) {
return arr;
}
function resetArr() public {
delete arr;
}
}
• Verify
• Code (9):
AddressBook.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@openzeppelin/contracts/access/Ownable.sol";
contract AddressBook is Ownable(msg.sender) {
string private salt = "value";
struct Contact {
uint id;
string firstName;
string lastName;
uint[] phoneNumbers;
}
Contact[] private contacts;
mapping(uint => uint) private idToIndex;
uint private nextId = 1;
error ContactNotFound(uint id);
function addContact(string calldata firstName, string calldata lastName, uint[] calldata phoneNumbers) external onlyOwner {
contacts.push(Contact(nextId, firstName, lastName, phoneNumbers));
idToIndex[nextId] = contacts.length - 1;
nextId++;
}
function deleteContact(uint id) external onlyOwner {
uint index = idToIndex[id];
if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
contacts[index] = contacts[contacts.length - 1];
idToIndex[contacts[index].id] = index;
contacts.pop();
delete idToIndex[id];
}
function getContact(uint id) external view returns (Contact memory) {
uint index = idToIndex[id];
if (index >= contacts.length || contacts[index].id != id) revert ContactNotFound(id);
return contacts[index];
}
function getAllContacts() external view returns (Contact[] memory) {
return contacts;
}
}
Other contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./AddressBook.sol";
contract AddressBookFactory {
string private salt = "value";
function deploy() external returns (AddressBook) {
AddressBook newAddressBook = new AddressBook();
newAddressBook.transferOwnership(msg.sender);
return newAddressBook;
}
}
• Code (9.1):
• Create another file and paste the second part of the code
• In the 4th field, enter the name of the file that you created before
• Copy and deploy the last file
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./9.sol";
contract AddressBookFactory {
string private salt = "value";
function deploy() external returns (AddressBook) {
AddressBook newAddressBook = new AddressBook();
newAddressBook.transferOwnership(msg.sender);
return newAddressBook;
}
}
• Verify
• Code (10):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract UnburnableToken {
string private salt = "value";
mapping(address => uint256) public balances;
uint256 public totalSupply;
uint256 public totalClaimed;
mapping(address => bool) private claimed;
// Custom errors
error TokensClaimed();
error AllTokensClaimed();
error UnsafeTransfer(address _to);
constructor() {
totalSupply = 100000000; // Set the total supply of tokens
}
// Public function to claim tokens
function claim() public {
if (totalClaimed >= totalSupply) revert AllTokensClaimed(); // Check if all tokens have been claimed
if (claimed[msg.sender]) revert TokensClaimed(); // Check if the caller has already claimed tokens
// Update balances and claimed status
balances[msg.sender] += 1000;
totalClaimed += 1000;
claimed[msg.sender] = true;
}
// Public function for safe token transfer
function safeTransfer(address _to, uint256 _amount) public {
// Check for unsafe transfer conditions, including if the target address has a non-zero ether balance
if (_to == address(0) || _to.balance == 0) revert UnsafeTransfer(_to);
// Ensure the sender has enough balance to transfer
require(balances[msg.sender] >= _amount, "Insufficient balance");
// Perform the transfer
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
• Verify
• Code (11):
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
contract WeightedVoting is ERC20 {
string private salt = "value";
using EnumerableSet for EnumerableSet.AddressSet;
error TokensClaimed();
error AllTokensClaimed();
error NoTokensHeld();
error QuorumTooHigh();
error AlreadyVoted();
error VotingClosed();
struct Issue {
EnumerableSet.AddressSet voters;
string issueDesc;
uint256 quorum;
uint256 totalVotes;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
bool passed;
bool closed;
}
struct SerializedIssue {
address[] voters;
string issueDesc;
uint256 quorum;
uint256 totalVotes;
uint256 votesFor;
uint256 votesAgainst;
uint256 votesAbstain;
bool passed;
bool closed;
}
enum Vote {
AGAINST,
FOR,
ABSTAIN
}
Issue[] internal issues;
mapping(address => bool) public tokensClaimed;
uint256 public maxSupply = 1000000;
uint256 public claimAmount = 100;
string saltt = "any";
constructor(string memory _name, string memory _symbol)
ERC20(_name, _symbol)
{
issues.push();
}
function claim() public {
if (totalSupply() + claimAmount > maxSupply) {
revert AllTokensClaimed();
}
if (tokensClaimed[msg.sender]) {
revert TokensClaimed();
}
_mint(msg.sender, claimAmount);
tokensClaimed[msg.sender] = true;
}
function createIssue(string calldata _issueDesc, uint256 _quorum)
external
returns (uint256)
{
if (balanceOf(msg.sender) == 0) {
revert NoTokensHeld();
}
if (_quorum > totalSupply()) {
revert QuorumTooHigh();
}
Issue storage _issue = issues.push();
_issue.issueDesc = _issueDesc;
_issue.quorum = _quorum;
return issues.length - 1;
}
function getIssue(uint256 _issueId)
external
view
returns (SerializedIssue memory)
{
Issue storage _issue = issues[_issueId];
return
SerializedIssue({
voters: _issue.voters.values(),
issueDesc: _issue.issueDesc,
quorum: _issue.quorum,
totalVotes: _issue.totalVotes,
votesFor: _issue.votesFor,
votesAgainst: _issue.votesAgainst,
votesAbstain: _issue.votesAbstain,
passed: _issue.passed,
closed: _issue.closed
});
}
function vote(uint256 _issueId, Vote _vote) public {
Issue storage _issue = issues[_issueId];
if (_issue.closed) {
revert VotingClosed();
}
if (_issue.voters.contains(msg.sender)) {
revert AlreadyVoted();
}
uint256 nTokens = balanceOf(msg.sender);
if (nTokens == 0) {
revert NoTokensHeld();
}
if (_vote == Vote.AGAINST) {
_issue.votesAgainst += nTokens;
} else if (_vote == Vote.FOR) {
_issue.votesFor += nTokens;
} else {
_issue.votesAbstain += nTokens;
}
_issue.voters.add(msg.sender);
_issue.totalVotes += nTokens;
if (_issue.totalVotes >= _issue.quorum) {
_issue.closed = true;
if (_issue.votesFor > _issue.votesAgainst) {
_issue.passed = true;
}
}
}
}
• Verify
• Code (12):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
interface ISubmission {
struct Haiku {
address author;
string line1;
string line2;
string line3;
}
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external;
// function ownerOf(uint256 _id) external view returns (address);
function counter() external view returns (uint256);
function shareHaiku(uint256 _id, address _to) external;
function getMySharedHaikus() external view returns (Haiku[] memory);
}
contract HaikuNFT is ERC721, ISubmission {
Haiku[] public haikus;
mapping(address => mapping(uint256 => bool)) public sharedHaikus;
uint256 public haikuCounter;
constructor() ERC721("HaikuNFT", "HAIKU") {
haikuCounter = 1;
}
string salt = "value";
function counter() external view override returns (uint256) {
return haikuCounter;
}
function mintHaiku(
string memory _line1,
string memory _line2,
string memory _line3
) external override {
// Check if the haiku is unique
string[3] memory haikusStrings = [_line1, _line2, _line3];
for (uint256 li = 0; li < haikusStrings.length; li++) {
string memory newLine = haikusStrings[li];
// string memory newHaikuString = string(
// abi.encodePacked(haikusStrings[li])
// );
for (uint256 i = 0; i < haikus.length; i++) {
Haiku memory existingHaiku = haikus[i];
string[3] memory existingHaikuStrings = [
existingHaiku.line1,
existingHaiku.line2,
existingHaiku.line3
];
for (uint256 eHsi = 0; eHsi < 3; eHsi++) {
string memory existingHaikuString = existingHaikuStrings[
eHsi
];
if (
keccak256(abi.encodePacked(existingHaikuString)) ==
keccak256(abi.encodePacked(newLine))
) {
revert HaikuNotUnique();
}
}
}
}
// Mint the haiku NFT
_safeMint(msg.sender, haikuCounter);
haikus.push(Haiku(msg.sender, _line1, _line2, _line3));
haikuCounter++;
}
function shareHaiku(uint256 _id, address _to) external override {
require(_id > 0 && _id <= haikuCounter, "Invalid haiku ID");
Haiku memory haikuToShare = haikus[_id - 1];
require(haikuToShare.author == msg.sender, "NotYourHaiku");
sharedHaikus[_to][_id] = true;
}
function getMySharedHaikus()
external
view
override
returns (Haiku[] memory)
{
uint256 sharedHaikuCount;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
sharedHaikuCount++;
}
}
Haiku[] memory result = new HaikuUnsupported embed;
uint256 currentIndex;
for (uint256 i = 0; i < haikus.length; i++) {
if (sharedHaikus[msg.sender][i + 1]) {
result[currentIndex] = haikus[i];
currentIndex++;
}
}
if (sharedHaikuCount == 0) {
revert NoHaikusShared();
}
return result;
}
error HaikuNotUnique();
error NotYourHaiku();
error NoHaikusShared();
}
• Verify
✅ That’s all!
✨ Collect this entry showing your support to our team! More collects-more guides!
No activity yet