Ethlint
openzeppelin-contracts
Ethlint | openzeppelin-contracts | |
---|---|---|
2 | 234 | |
918 | 24,143 | |
- | 1.0% | |
0.0 | 9.5 | |
about 1 year ago | 4 days ago | |
JavaScript | JavaScript | |
MIT License | MIT License |
Stars - the number of stars that a project has on GitHub. Growth - month over month growth in stars.
Activity is a relative number indicating how actively a project is being developed. Recent commits have higher weight than older ones.
For example, an activity of 9.0 indicates that a project is amongst the top 10% of the most actively developed projects that we are tracking.
Ethlint
-
Secure Smart Contract Tools—An End-to-End Developer’s Guide
Finally, linting is a valuable tool for finding potential issues in smart contract code. It can find stylistic errors, violations of programming conventions, and unsafe constructs in your code. There are many great linters available, such as ETHLint (Formerly Solium). Linting can help find potential problems—even security problems such as re-entrancy vulnerabilities—before they become costly mistakes.
-
Introducción a los Contratos Inteligentes con Solidity
pragma solidity ^0.5.10; // Imports symbols from other files into the current contract. // In this case, a series of helper contracts from OpenZeppelin. // Learn more: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol"; import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol"; // The `is` keyword is used to inherit functions and keywords from external contracts. // In this case, `CryptoPizza` inherits from the `IERC721` and `ERC165` contracts. // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance contract CryptoPizza is IERC721, ERC165 { // Uses OpenZeppelin's SafeMath library to perform arithmetic operations safely. // Learn more: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath using SafeMath for uint256; // Constant state variables in Solidity are similar to other languages // but you must assign from an expression which is constant at compile time. // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables uint256 constant dnaDigits = 10; uint256 constant dnaModulus = 10 ** dnaDigits; bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Struct types let you define your own type // Learn more: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs struct Pizza { string name; uint256 dna; } // Creates an empty array of Pizza structs Pizza[] public pizzas; // Mapping from pizza ID to its owner's address mapping(uint256 => address) public pizzaToOwner; // Mapping from owner's address to number of owned token mapping(address => uint256) public ownerPizzaCount; // Mapping from token ID to approved address mapping(uint256 => address) pizzaApprovals; // You can nest mappings, this example maps owner to operator approvals mapping(address => mapping(address => bool)) private operatorApprovals; // Internal function to create a random Pizza from string (name) and DNA function _createPizza(string memory _name, uint256 _dna) // The `internal` keyword means this function is only visible // within this contract and contracts that derive this contract // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters internal // `isUnique` is a function modifier that checks if the pizza already exists // Learn more: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers isUnique(_name, _dna) { // Adds Pizza to array of Pizzas and get id uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1); // Checks that Pizza owner is the same as current user // Learn more: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions // note that address(0) is the zero address, // indicating that pizza[id] is not yet allocated to a particular user. assert(pizzaToOwner[id] == address(0)); // Maps the Pizza to the owner pizzaToOwner[id] = msg.sender; ownerPizzaCount[msg.sender] = SafeMath.add( ownerPizzaCount[msg.sender], 1 ); } // Creates a random Pizza from string (name) function createRandomPizza(string memory _name) public { uint256 randDna = generateRandomDna(_name, msg.sender); _createPizza(_name, randDna); } // Generates random DNA from string (name) and address of the owner (creator) function generateRandomDna(string memory _str, address _owner) public // Functions marked as `pure` promise not to read from or modify the state // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions pure returns (uint256) { // Generates random uint from string (name) + address (owner) uint256 rand = uint256(keccak256(abi.encodePacked(_str))) + uint256(_owner); rand = rand % dnaModulus; return rand; } // Returns array of Pizzas found by owner function getPizzasByOwner(address _owner) public // Functions marked as `view` promise not to modify state // Learn more: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions view returns (uint256[] memory) { // Uses the `memory` storage location to store values only for the // lifecycle of this function call. // Learn more: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack uint256[] memory result = new uint256[](ownerPizzaCount[_owner]); uint256 counter = 0; for (uint256 i = 0; i < pizzas.length; i++) { if (pizzaToOwner[i] == _owner) { result[counter] = i; counter++; } } return result; } // Transfers Pizza and ownership to other address function transferFrom(address _from, address _to, uint256 _pizzaId) public { require(_from != address(0) && _to != address(0), "Invalid address."); require(_exists(_pizzaId), "Pizza does not exist."); require(_from != _to, "Cannot transfer to the same address."); require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved."); ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1); ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1); pizzaToOwner[_pizzaId] = _to; // Emits event defined in the imported IERC721 contract emit Transfer(_from, _to, _pizzaId); _clearApproval(_to, _pizzaId); } /** * Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; * otherwise, the transfer is reverted. */ function safeTransferFrom(address from, address to, uint256 pizzaId) public { // solium-disable-next-line arg-overflow this.safeTransferFrom(from, to, pizzaId, ""); } /** * Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, * which is called upon a safe transfer, and return the magic value * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; * otherwise, the transfer is reverted. */ function safeTransferFrom( address from, address to, uint256 pizzaId, bytes memory _data ) public { this.transferFrom(from, to, pizzaId); require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received."); } /** * Internal function to invoke `onERC721Received` on a target address * The call is not executed if the target address is not a contract */ function _checkOnERC721Received( address from, address to, uint256 pizzaId, bytes memory _data ) internal returns (bool) { if (!isContract(to)) { return true; } bytes4 retval = IERC721Receiver(to).onERC721Received( msg.sender, from, pizzaId, _data ); return (retval == _ERC721_RECEIVED); } // Burns a Pizza - destroys Token completely // The `external` function modifier means this function is // part of the contract interface and other contracts can call it function burn(uint256 _pizzaId) external { require(msg.sender != address(0), "Invalid address."); require(_exists(_pizzaId), "Pizza does not exist."); require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved."); ownerPizzaCount[msg.sender] = SafeMath.sub( ownerPizzaCount[msg.sender], 1 ); pizzaToOwner[_pizzaId] = address(0); } // Returns count of Pizzas by address function balanceOf(address _owner) public view returns (uint256 _balance) { return ownerPizzaCount[_owner]; } // Returns owner of the Pizza found by id function ownerOf(uint256 _pizzaId) public view returns (address _owner) { address owner = pizzaToOwner[_pizzaId]; require(owner != address(0), "Invalid Pizza ID."); return owner; } // Approves other address to transfer ownership of Pizza function approve(address _to, uint256 _pizzaId) public { require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner."); pizzaApprovals[_pizzaId] = _to; emit Approval(msg.sender, _to, _pizzaId); } // Returns approved address for specific Pizza function getApproved(uint256 _pizzaId) public view returns (address operator) { require(_exists(_pizzaId), "Pizza does not exist."); return pizzaApprovals[_pizzaId]; } /** * Private function to clear current approval of a given token ID * Reverts if the given address is not indeed the owner of the token */ function _clearApproval(address owner, uint256 _pizzaId) private { require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner."); require(_exists(_pizzaId), "Pizza does not exist."); if (pizzaApprovals[_pizzaId] != address(0)) { pizzaApprovals[_pizzaId] = address(0); } } /* * Sets or unsets the approval of a given operator * An operator is allowed to transfer all tokens of the sender on their behalf */ function setApprovalForAll(address to, bool approved) public { require(to != msg.sender, "Cannot approve own address"); operatorApprovals[msg.sender][to] = approved; emit ApprovalForAll(msg.sender, to, approved); } // Tells whether an operator is approved by a given owner function isApprovedForAll(address owner, address operator) public view returns (bool) { return operatorApprovals[owner][operator]; } // Takes ownership of Pizza - only for approved users function takeOwnership(uint256 _pizzaId) public { require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved."); address owner = this.ownerOf(_pizzaId); this.transferFrom(owner, msg.sender, _pizzaId); } // Checks if Pizza exists function _exists(uint256 pizzaId) internal view returns (bool) { address owner = pizzaToOwner[pizzaId]; return owner != address(0); } // Checks if address is owner or is approved to transfer Pizza function _isApprovedOrOwner(address spender, uint256 pizzaId) internal view returns (bool) { address owner = pizzaToOwner[pizzaId]; // Disable solium check because of // https://github.com/duaraghav8/Solium/issues/175 // solium-disable-next-line operator-whitespace return (spender == owner || this.getApproved(pizzaId) == spender || this.isApprovedForAll(owner, spender)); } // Check if Pizza is unique and doesn't exist yet modifier isUnique(string memory _name, uint256 _dna) { bool result = true; for (uint256 i = 0; i < pizzas.length; i++) { if ( keccak256(abi.encodePacked(pizzas[i].name)) == keccak256(abi.encodePacked(_name)) && pizzas[i].dna == _dna ) { result = false; } } require(result, "Pizza with such name already exists."); _; } // Returns whether the target address is a contract function isContract(address account) internal view returns (bool) { uint256 size; // Currently there is no better way to check if there is a contract in an address // than to check the size of the code at that address. // See https://ethereum.stackexchange.com/a/14016/36603 // for more details about how this works. // TODO Check this again before the Serenity release, because all addresses will be // contracts then. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } }
openzeppelin-contracts
-
Mode - Comprehensive Starter Guide
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/token/ERC20/ERC20.sol"; interface Sfs { function register(address _recipient) external returns (uint256 tokenId); } contract ModeToken is ERC20 { address feeReceiver = msg.sender; constructor() ERC20("ModeTokenSFSTest", "SFST2") { //Example amount to mint our ERC20 _mint(msg.sender, 1000 10 * 18); // This is the SFS contract address on testnet Sfs sfsContract = Sfs(0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6); //Registers this contract and assigns the NFT //to the deployer of this contract sfsContract.register(msg.sender); } }
-
Blockchain transactions decoding: making wallet activity understandable
Lets look the events of Open Zeppelin’s ERC20 token contract:
- Construir e implementar un VAULT (bóveda) ERC20 en Shardeum
-
Are ERC-777 Unsafe?
ERC-777 is difficult to implement properly, due to its susceptibility to different forms of attack(opens in a new tab). It is recommended to use ERC-20 instead. This page remains as a historical archive.
- OpenZeppelin is trying to avoid paying a bounty for a vulnerability that caused $1,1B worth of assets freeze
- Security improvements of the ERC20 token standard
- Ethereums most used token standard ERC20 requires security enhancements
- The most used Ethereums token standard (ERC20) requires a security patch.
What are some alternatives?
solhint - Solhint is an open-source project to provide a linting utility for Solidity code.
solmate - Modern, opinionated, and gas optimized building blocks for smart contract development.
truffle-flattener - Truffle Flattener concats solidity files from Truffle and Buidler projects with all of their dependencies
hardhat - Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software.
DeFi-Developer-Road-Map - DeFi Developer roadmap is a curated Developer handbook which includes a list of the best tools for DApps development, resources and references!
ERC721A - https://ERC721A.org
Safemoon.sol - safemoon contract
solidity - Solidity, the Smart Contract Programming Language
truffle - :warning: The Truffle Suite is being sunset. For information on ongoing support, migration options and FAQs, visit the Consensys blog. Thank you for all the support over the years.
poap-contracts - The Proof of Attendance Protocol Ethereum contracts
openzeppelin-solidity - OpenZeppelin Contracts is a library for secure smart contract development. [Moved to: https://github.com/OpenZeppelin/openzeppelin-contracts]
matic-gas-prices - Displays current gas prices on the Polygon (MATIC) network.