Skip to content

Commit

Permalink
Adding smart contracts required for usdc locking on the ethereum network
Browse files Browse the repository at this point in the history
  • Loading branch information
Caneryy committed Jan 6, 2024
1 parent abebe36 commit 97e9113
Show file tree
Hide file tree
Showing 13 changed files with 9,891 additions and 0 deletions.
9 changes: 9 additions & 0 deletions evm-contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules/
build/

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
Empty file.
101 changes: 101 additions & 0 deletions evm-contracts/contracts/Bridge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Bridge {
address public owner;
IERC20 public usdcToken;

struct BridgeTransfer {
address sender;
uint256 amount;
bytes32 recipient;
bytes4 destination;
bool completed;
}

mapping(uint256 => BridgeTransfer) public transfers;
mapping(address => uint256) public balances;
mapping(uint256 => bool) public processedTransactions;

uint256 public nextTransferId;

event Deposit(address indexed sender, uint256 amount, uint256 transferId);
event TransferCompleted(uint256 transferId);
event ReleaseTokens(
address indexed recipient,
uint256 amount,
uint256 transactionId
);
event Withdrawal(address indexed user, uint256 amount);

modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}

constructor(address _usdcTokenAddress) {
owner = msg.sender;
usdcToken = IERC20(_usdcTokenAddress);
}

function deposit(
uint256 amount,
bytes32 recipient,
bytes4 destination
) public {
require(
usdcToken.transferFrom(msg.sender, address(this), amount),
"Transfer failed"
);
transfers[nextTransferId] = BridgeTransfer(
msg.sender,
amount,
recipient,
destination,
false
);
balances[msg.sender] += amount;

emit Deposit(msg.sender, amount, nextTransferId);
nextTransferId++;
}

function completeTransfer(uint256 transferId) public onlyOwner {
BridgeTransfer storage transfer = transfers[transferId];
require(!transfer.completed, "Transfer already completed");
transfer.completed = true;
balances[transfer.sender] -= transfer.amount;

emit TransferCompleted(transferId);
}

function releaseTokens(
address recipient,
uint256 amount,
uint256 transactionId
) public onlyOwner {
require(
!processedTransactions[transactionId],
"Transaction already processed"
);
processedTransactions[transactionId] = true;
require(usdcToken.transfer(recipient, amount), "Transfer failed");
emit ReleaseTokens(recipient, amount, transactionId);
}

function withdraw() public {
uint256 userBalance = balances[msg.sender];
require(userBalance > 0, "No balance to withdraw");

balances[msg.sender] = 0;
require(usdcToken.transfer(msg.sender, userBalance), "Transfer failed");

emit Withdrawal(msg.sender, userBalance);
}

function getBalanceOnContract() public view returns (uint256) {
return balances[msg.sender];
}
}
20 changes: 20 additions & 0 deletions evm-contracts/contracts/MyUsdc.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract MyUsdc is ERC20, Ownable, ERC20Permit {
constructor(address initialOwner)
ERC20("MyUsdc", "MUSDC")
Ownable(initialOwner)
ERC20Permit("MyUsdc")
{
_mint(msg.sender, 1000000 * 10 ** decimals());
}

function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
40 changes: 40 additions & 0 deletions evm-contracts/contracts/ReceiveUsdc.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract ReceiveUSDC {
IERC20 public usdcToken;
address usdcAddress;

mapping(address => uint256) balances;

event Received(address sender, uint256 amount);

constructor(address _usdcAddress) {
usdcAddress = _usdcAddress;
usdcToken = IERC20(_usdcAddress);
}

function getBalance() public view returns (uint256) {
return usdcToken.balanceOf(address(this));
}

function getBalanceOnContract() public view returns (uint256) {
return balances[msg.sender];
}

function lockToken(
uint128 id,
uint256 amount,
bytes32 recipient,
bytes4 destination
) external {
require(
usdcToken.transferFrom(msg.sender, address(this), amount),
"Transfer failed"
);
balances[msg.sender] += amount;
emit Received(msg.sender, amount);
}
}
Empty file.
13 changes: 13 additions & 0 deletions evm-contracts/migrations/2_deploy_contracts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const MyUsdc = artifacts.require("MyUsdc");
const ReceiveUSDC = artifacts.require("ReceiveUSDC");

require('dotenv').config();
const { ADDRESS } = process.env;

module.exports = async function (deployer) {

await deployer.deploy(MyUsdc, ADDRESS);
await MyUsdc.deployed()

await deployer.deploy(ReceiveUSDC, MyUsdc.address);
};
Loading

0 comments on commit 97e9113

Please sign in to comment.