Code Monkey home page Code Monkey logo

facet-scan's Introduction

Getting Started

Environment Setup

Before starting the development server, you need to set up the environment variables. Create a .env file in the root directory of this project. You can take reference from the .sample.env file which looks like this:

NEXT_PUBLIC_NETWORK=goerli
NEXT_PUBLIC_API_BASE_URI=https://goerli-api.facet.org

If you decide to clone the facet-vm repo and get the API running on your local machine, replace https://goerli-api.facet.org in the .env file with your localhost URL.

Running the Development Server

Once the environment is set up:

yarn dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying pages/index.tsx. The page auto-updates as you edit the file.

Learn More

To learn more about this stack, take a look at the following resources:

facet-scan's People

Contributors

mikeahirsch avatar rogerpodacter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

facet-scan's Issues

Uniswapv2pair.sol conversion

import 'ethscriptions/contracts/DumbContract.sol';
import 'ethscriptions/contracts/UniswapV2Router02.sol';

class Contracts::RubidityUniswapV2Pair < Contract
address :factory
address :token0
address :token1
uint112 :reserve0
uint112 :reserve1
uint32 :blockTimestampLast
uint :price0CumulativeLast
uint :price1CumulativeLast
uint :kLast
uint :unlocked

bytes4 :SELECTOR
address :feeTo
uint :MINIMUM_LIQUIDITY

constructor(_token0: :address, _token1: :address) {
@factory = msg.sender
@token0 = _token0
@Token1 = _token1
@unlocked = 1
@selector = bytes4(keccak256(bytes('transfer(address,uint256)')))
@feeto = IUniswapV2Factory(IUniswapV2Router02.new().factory()).feeTo()
@MINIMUM_LIQUIDITY = 10**3
}

modifier onlyOwner {
require(msg.sender == @factory, 'UniswapV2: FORBIDDEN')
_;
}

modifier lock {
require(unlocked == 1, 'UniswapV2: LOCKED')
unlocked = 0
_;
unlocked = 1
}

function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
_reserve0 = reserve0
_reserve1 = reserve1
_blockTimestampLast = blockTimestampLast
}

function _safeTransfer(_token: :address, _to: :address, _value: :uint) private {
(bool success, bytes memory data) = _token.call(abi.encodeWithSelector(SELECTOR, _to, _value))
require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED')
}

function mint(_to: :address) external lock returns (uint liquidity) {
(uint112 _reserve0, uint112 _reserve1,) = getReserves()
uint balance0 = DumbContract(token0).balanceOf(address(this))
uint balance1 = DumbContract(token1).balanceOf(address(this))
uint amount0 = balance0.sub(_reserve0)
uint amount1 = balance1.sub(_reserve1)

bool feeOn = _mintFee(_reserve0, _reserve1)
uint _totalSupply = totalSupply
if (_totalSupply == 0) {
  liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY)
  _mint(address(0), MINIMUM_LIQUIDITY)
} else {
  liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1)
}
require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED')
_mint(_to, liquidity)

_update(balance0, balance1, _reserve0, _reserve1)
if (feeOn) kLast = uint(reserve0).mul(reserve1)

}

// Other functions like burn, swap, skim, sync need to be adapted similarly.
// Make sure to handle state variables and external contract interactions correctly.

// ...
}

You would need to adapt other functions like burn, swap, skim, and sync similarly and ensure correct handling of state variables and external contract interactions.

Gas efficiency snippet

class Contracts::ERC20Transfer < ContractImplementation
is :ERC20Storage

function :transfer, { to: :addressOrDumbContract, amount: :uint256 }, :public do
require(s.balanceOf[msg.sender] >= amount, 'Insufficient balance')

s.balanceOf[msg.sender] -= amount
s.balanceOf[to] += amount

emit :Transfer, from: msg.sender, to: to, amount: amount

end
end

UniswapV2ERC20.sol conversion

import 'ethscriptions/contracts/DumbContract.sol';

class Contracts::UniswapV2ERC20 < Contract
string :name
string :symbol
uint8 :decimals
uint :totalSupply
mapping(address => uint) :balanceOf
mapping(address => mapping(address => uint)) :allowance

bytes32 :DOMAIN_SEPARATOR
bytes32 :PERMIT_TYPEHASH
mapping(address => uint) :nonces

event Approval(address indexed owner, address indexed spender, uint value)
event Transfer(address indexed from, address indexed to, uint value)

constructor() {
@name = 'Uniswap V2'
@symbol = 'UNI-V2'
@dECIMALS = 18
@totalSupply = 0
@DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes(name)),
keccak256(bytes('1')),
ChainId,
address(this)
)
)
@PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9
}

function mint(address to, uint value) internal {
totalSupply = totalSupply.add(value)
balanceOf[to] = balanceOf[to].add(value)
emit Transfer(address(0), to, value)
}

function burn(address from, uint value) internal {
balanceOf[from] = balanceOf[from].sub(value)
totalSupply = totalSupply.sub(value)
emit Transfer(from, address(0), value)
}

function approve(address spender, uint value) external returns (bool) {
allowance[msg.sender][spender] = value
emit Approval(msg.sender, spender, value)
return true
}

function transfer(address to, uint value) external returns (bool) {
require(balanceOf[msg.sender] >= value, 'UniswapV2: INSUFFICIENT_BALANCE')
balanceOf[msg.sender] = balanceOf[msg.sender].sub(value)
balanceOf[to] = balanceOf[to].add(value)
emit Transfer(msg.sender, to, value)
return true
}

function transferFrom(address from, address to, uint value) external returns (bool) {
require(balanceOf[from] >= value, 'UniswapV2: INSUFFICIENT_BALANCE')
require(allowance[from][msg.sender] >= value, 'UniswapV2: ALLOWANCE_EXCEEDED')
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value)
balanceOf[from] = balanceOf[from].sub(value)
balanceOf[to] = balanceOf[to].add(value)
emit Transfer(from, to, value)
return true
}

function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
require(deadline >= block.timestamp, 'UniswapV2: EXPIRED')
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
)
address recoveredAddress = ecrecover(digest, v, r, s)
require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE')
allowance[owner][spender] = value
emit Approval(owner, spender, value)
}
}

Upgradability contract

class Contracts::ERC20Storage < ContractImplementation
string :public, :name
string :public, :symbol
uint256 :public, :decimals
uint256 :public, :totalSupply
mapping ({ addressOrDumbContract: :uint256 }), :public, :balanceOf
mapping ({ addressOrDumbContract: mapping(addressOrDumbContract: :uint256) }), :public, :allowance
end

class Contracts::ERC20Logic < ContractImplementation
is :ERC20Storage

constructor(name: :string, symbol: :string, decimals: :uint256) {
s.name = name
s.symbol = symbol
s.decimals = decimals
}

function :transfer, { to: :addressOrDumbContract, amount: :uint256 }, :public, :virtual, returns: :bool do
require(s.balanceOf[msg.sender] >= amount, 'Insufficient balance')

s.balanceOf[msg.sender] -= amount
s.balanceOf[to] += amount

emit :Transfer, from: msg.sender, to: to, amount: amount

return true

end

Add other functions and logic here

end

class Contracts::ERC20Proxy < ContractImplementation
is :ERC20Storage

mapping ({ addressOrDumbContract: :addressOrDumbContract }), :internal, :virtual, :logicContracts

constructor(logicContractAddress: :addressOrDumbContract) {
s.logicContracts[msg.sender] = logicContractAddress
}

function :fallback, :public do
logicContract = s.logicContracts[msg.sender]
delegateCall(logicContract, msg.data)
end
end

ERC20Storage defines the contract's storage variables.
ERC20Logic contains the contract's logic for functions like transfer. It inherits from ERC20Storage.
ERC20Proxy delegates calls to the logic contract and maintains a mapping of logic contracts for each user.
With this structure, you can deploy a new ERC20Logic contract with updated logic and then update the ERC20Proxy contract to point to the new logic contract address

I want to contribute to UI / UX Design

Hello, I would like to offer support to the web3 ecosystem as a frontend developer. Before I begin development, I wanted to inquire whether there is such a need or if it is allowed.

The reason for my request is that I am currently in a job search, and I believe that the support I provide to a web3 project could serve as a reference.

Thanks.

Proposal for Snapshot Rewards Contract

Issue Summary:

I would like to propose the implementation of a simple Snapshot Rewards Contract in Solidity.

Background:

The goal is to create a contract where users can take snapshots of their token balances and later claim rewards based on the difference between their current balance and the balance at the time of the snapshot.

Proposed Solution:

We can achieve this functionality with the following contract:

class SnapshotRewards < Contracts::ERC20
  pragma :rubidity, "1.0.0"

  constructor(name: :string, symbol: :string, decimals: :uint256) {
    super(name, symbol, decimals)
  end

  # Take a snapshot of the current reward balance
  function :takeSnapshot, :public, :virtual do
    s.snapshotBalance[msg.sender] = s.balanceOf[msg.sender]
  end

  # Claim rewards based on the snapshot
  function :claimReward, :public, :virtual do
    snapshotBalance = s.snapshotBalance[msg.sender]
    currentBalance = s.balanceOf[msg.sender]
    
    if snapshotBalance > 0 && currentBalance > snapshotBalance
      reward = currentBalance - snapshotBalance
      s.snapshotBalance[msg.sender] = currentBalance
      super.transfer(to: msg.sender, amount: reward)
    end
  end
end

Expected Result:

The contract allows users to take snapshots of their token balances and claim rewards based on the difference.

Additional Information:

This contract does not involve staking and is designed for a simple reward distribution mechanism.

Please let me know your thoughts and any feedback on this proposal.

Reentrancy Vulnerability in Smart Contract

Issue Description:
A potential reentrancy vulnerability exists within the smart contract code. Reentrancy vulnerabilities can allow attackers to manipulate contract state and exploit unintended behavior, potentially leading to financial losses or unauthorized access to funds. This issue report aims to highlight the situation and provide recommendations for mitigating the vulnerability.

Affected Contract:
Contracts::PublicMintERC20 and related contracts.

Details:
The codebase follows good practices for security, and at first glance, there doesn't appear to be a direct reentrancy vulnerability in the provided code. The contract seems to be handling token minting and transfers within its own functions.

Mitigation Recommendation:
To further ensure the contract's security, it's recommended to adhere to the "pull" mechanism for transferring tokens. This helps prevent potential reentrancy attacks by having external contracts initiate token transfers rather than the smart contract initiating transfers directly.

Proposed Solution:

When interacting with external contracts, ensure that the recipient (external contract) initiates the transfer of tokens or Ether.
Consider implementing a design where external contracts request funds from your contract before receiving them.
Validate the requests and ensure that the recipient contract is in a safe state to receive the funds before approving the transfer.
Preventive Measures:

Apply the checks-effects-interactions pattern to critical functions to minimize the risk of reentrancy.
Use state variables or reentrancy guards to track ongoing executions of sensitive functions.
Conduct comprehensive testing and review the code with the goal of identifying any possible reentrancy scenarios.
Recommendation Summary:
Given the current code and its structure, there isn't an immediate reentrancy vulnerability. However, to enhance the contract's security posture and minimize potential risks, it is advised to adopt the "pull" mechanism for token transfers, following the best practices outlined above.

It's essential to conduct a thorough security audit by experienced smart contract auditors to identify and address any potential vulnerabilities before deploying the contract to a production environment.

Severity:
Low/Medium

Acknowledgment:
This issue report was created to promote awareness and best practices for secure smart contract development. It is not a substitute for professional security auditing and consultation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.