Address Contract Verified
Address
0xBF9D3824B1CB694bd496c73CfE549e5D7ab54818
Balance
0 ETH
Nonce
1
Code Size
3326 bytes
Creator
0x783bBC93...2533 at tx 0x74dd587d...5fd78d
Indexed Transactions
0
Contract Bytecode
3326 bytes
0x608060405234801561001057600080fd5b50600436106101425760003560e01c80639fb88144116100b8578063e59a57191161007c578063e59a5719146102e6578063ebbbcf82146102f9578063ecdd75d014610302578063efd80afb14610315578063f2fde38b14610328578063fe0bfc991461033b57600080fd5b80639fb881441461027c578063bed998501461029c578063c34b6011146102a9578063d710c615146102c0578063e06dd2e9146102d357600080fd5b806356aa595f1161010a57806356aa595f146101e65780635c975abb146101fd578063715018a61461021357806375d9f4cb1461021b5780638da5cb5b1461022e57806395fd8b391461025857600080fd5b80631b6c6c70146101475780631f1a202c146101805780632541e87d146101ab57806337a3ce54146101be5780633db55bcb146101d3575b600080fd5b61016d610155366004610b15565b63ffffffff1660009081526004602052604090205490565b6040519081526020015b60405180910390f35b6005546101969062010000900463ffffffff1681565b60405163ffffffff9091168152602001610177565b61016d6101b9366004610b37565b61034e565b6101d16101cc366004610b15565b6103d5565b005b6101d16101e1366004610b50565b610406565b60055461019690600160501b900463ffffffff1681565b60005460ff166040519015158152602001610177565b6101d161088f565b6101d1610229366004610b7a565b6108a3565b60005461010090046001600160a01b03165b6040516001600160a01b039091168152602001610177565b60055461026a90610100900460ff1681565b60405160ff9091168152602001610177565b61016d61028a366004610b15565b60046020526000908152604090205481565b60055461026a9060ff1681565b60055461019690600160301b900463ffffffff1681565b6101d16102ce366004610b15565b6108cd565b6101d16102e1366004610b37565b6108fb565b600254610240906001600160a01b031681565b61016d60065481565b6101d1610310366004610ba3565b610908565b600354610240906001600160a01b031681565b6101d1610336366004610b7a565b610958565b6101d1610349366004610b15565b6109d1565b600654600554600091906103779063ffffffff600160501b820481169162010000900416610bdc565b63ffffffff166103879190610c04565b6005546103a190600160301b900463ffffffff1684610c04565b6103b390670de0b6b3a7640000610c04565b6103c590670de0b6b3a7640000610c04565b6103cf9190610c1b565b92915050565b6103dd6109fd565b6005805463ffffffff909216600160301b0269ffffffff00000000000019909216919091179055565b61040e610a5d565b600554600160501b900463ffffffff1661047a5760405162461bcd60e51b815260206004820152602260248201527f6275794279746573546f436572746966793a2052617465455448455552203c3d604482015261020360f41b60648201526084015b60405180910390fd5b6000600654116104d85760405162461bcd60e51b815260206004820152602360248201527f6275794279746573546f436572746966793a205261746542434454455552203c60448201526203d20360ec1b6064820152608401610471565b6003546001600160a01b031661053c5760405162461bcd60e51b8152602060048201526024808201527f6275794279746573546f436572746966793a20424344416464726573732069736044820152630203078360e41b6064820152608401610471565b60055462010000900463ffffffff1681101561058c5760405162461bcd60e51b815260206004820152600f60248201526e6e62427974657320746f6f206c6f7760881b6044820152606401610471565b60006105978261034e565b6001546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156105e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106089190610c3d565b101561064d5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610471565b600154604051636eb1769f60e11b815233600482015230602482015282916001600160a01b03169063dd62ed3e90604401602060405180830381865afa15801561069b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106bf9190610c3d565b10156107065760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b6044820152606401610471565b600554610100900460ff16156107b8576001546003546005546001600160a01b03928316926323b872dd92339291169060649061074b90610100900460ff1687610c04565b6107559190610c1b565b6040518463ffffffff1660e01b815260040161077393929190610c56565b6020604051808303816000875af1158015610792573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b69190610c7a565b505b60055460ff1615610860576001546002546005546001600160a01b03928316926323b872dd9233929116906064906107f39060ff1687610c04565b6107fd9190610c1b565b6040518463ffffffff1660e01b815260040161081b93929190610c56565b6020604051808303816000875af115801561083a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085e9190610c7a565b505b63ffffffff831660009081526004602052604081208054849290610885908490610c9c565b9091555050505050565b6108976109fd565b6108a16000610aa3565b565b6108ab6109fd565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b6108d56109fd565b6005805463ffffffff909216600160501b0263ffffffff60501b19909216919091179055565b6109036109fd565b600655565b6109106109fd565b60648160ff16111561092157600080fd5b6005805460ff191660ff831617905561093b816064610caf565b600560016101000a81548160ff021916908360ff16021790555050565b6109606109fd565b6001600160a01b0381166109c55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610471565b6109ce81610aa3565b50565b6109d96109fd565b6005805463ffffffff909216620100000265ffffffff000019909216919091179055565b6000546001600160a01b036101009091041633146108a15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610471565b60005460ff16156108a15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610471565b600080546001600160a01b03838116610100818102610100600160a81b0319851617855560405193049190911692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a35050565b803563ffffffff81168114610b1057600080fd5b919050565b600060208284031215610b2757600080fd5b610b3082610afc565b9392505050565b600060208284031215610b4957600080fd5b5035919050565b60008060408385031215610b6357600080fd5b610b6c83610afc565b946020939093013593505050565b600060208284031215610b8c57600080fd5b81356001600160a01b0381168114610b3057600080fd5b600060208284031215610bb557600080fd5b813560ff81168114610b3057600080fd5b634e487b7160e01b600052601160045260246000fd5b63ffffffff818116838216028082169190828114610bfc57610bfc610bc6565b505092915050565b80820281158282048414176103cf576103cf610bc6565b600082610c3857634e487b7160e01b600052601260045260246000fd5b500490565b600060208284031215610c4f57600080fd5b5051919050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b600060208284031215610c8c57600080fd5b81518015158114610b3057600080fd5b808201808211156103cf576103cf610bc6565b60ff82811682821603908111156103cf576103cf610bc656fea26469706673582212207a175193c586f31d0a590c6eb4cf30f51ff670c6d0a5c93e87b48cc73d4deac864736f6c63430008120033
Verified Source Code Full Match
Compiler: v0.8.18+commit.87f61d96
EVM: paris
Optimization: Yes (100 runs)
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Pausable.sol 105 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
IERC20.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
BCDTBurning.sol 135 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
contract BCDTBurning is Pausable, Ownable {
IERC20 private BCDT;
// Global variables concerning token
address public burnTokenToAddress =
0x0000000000000000000000000000000000000001;
// Initial addresses used for staging platform on mainnet or testnet
address public BCDAddress;
mapping(uint32 => uint256) public nbBytesToCertify;
//Percentage of tokens burned when buying bytes to certified
uint8 public burnRate = 25;
//Percentage of tokens send to BCD used when buying bytes to certified
uint8 public BCDRate = 75;
// Size retained for a unit of data to be issued (aka "credit")
uint32 public creditDataSize = 600;
// Price retained for a credit (in euro cents)
uint32 public creditPriceInEuro = 80;
// Initial rate between ETH and EUR * 100, will be updated by Oracle
uint32 public rateETHEUR = 15480;
// Initial rate between BCDT and ETH * 1E18, will be updated by Oracle
uint256 public rateBCDTETH = 64100000000000;
constructor(address _BCDTAddress) {
BCDT = IERC20(_BCDTAddress);
}
function updateBurnRate(uint8 _newBurnRate) public onlyOwner {
require(_newBurnRate <= 100);
burnRate = _newBurnRate;
BCDRate = 100 - _newBurnRate;
}
function updateCreditDataSize(uint32 _creditDataSize) public onlyOwner {
creditDataSize = _creditDataSize;
}
function updateCreditPriceInEuro(
uint32 _creditPriceInEuro
) public onlyOwner {
creditPriceInEuro = _creditPriceInEuro;
}
function updateBCDAddress(address _newBCDAddress) public onlyOwner {
BCDAddress = _newBCDAddress;
}
function updateRateETHEUR(uint32 _newRateETHEUR) public onlyOwner {
rateETHEUR = _newRateETHEUR;
}
function updateRateBCDTETH(uint256 _newRateBCDTETH) public onlyOwner {
rateBCDTETH = _newRateBCDTETH;
}
function getNeededTokensForBytesToCertify(
uint256 _nbBytesToCertify
) public view returns (uint256) {
// Tokens needed to prepaid X bytes of data to certified =
// _nbBytesToCertify * creditPriceInEuro / creditDataSize / rateETHEUR / rateBCDTETH
// , respecting decimals
// Be aware that operations are executed sequentially
// Multiplication by 1 ether to avoid conversion issues
return
(_nbBytesToCertify * creditPriceInEuro * 1 ether * 1 ether) /
(creditDataSize * rateETHEUR * rateBCDTETH);
}
// Function to buy bytes with Tokens.
function buyBytesToCertify(
uint32 _issuerID,
uint256 _nbBytesToCertify
) public whenNotPaused {
require(rateETHEUR > 0, "buyBytesToCertify: RateETHEUR <= 0");
require(rateBCDTETH > 0, "buyBytesToCertify: RateBCDTEUR <= 0");
require(
BCDAddress != address(0x0),
"buyBytesToCertify: BCDAddress is 0x0"
);
require(_nbBytesToCertify >= creditDataSize, "nbBytes too low");
uint256 neededTokens = getNeededTokensForBytesToCertify(
_nbBytesToCertify
);
// Check if sender has enought tokens
require(
BCDT.balanceOf(msg.sender) >= neededTokens,
"Insufficient balance"
);
require(
BCDT.allowance(msg.sender, address(this)) >= neededTokens,
"Insufficient allowance"
);
if (BCDRate > 0) {
BCDT.transferFrom(
msg.sender,
BCDAddress,
(neededTokens * BCDRate) / 100
);
}
if (burnRate > 0) {
BCDT.transferFrom(
msg.sender,
burnTokenToAddress,
(neededTokens * burnRate) / 100
);
}
nbBytesToCertify[_issuerID] += _nbBytesToCertify;
}
// Check how many bytes an issuer adress could certified
function issuerNbBytesToCertifyBalance(
uint32 _issuerId
) public view returns (uint256) {
return nbBytesToCertify[_issuerId];
}
}
Read Contract
BCDAddress 0xefd80afb → address
BCDRate 0x95fd8b39 → uint8
burnRate 0xbed99850 → uint8
burnTokenToAddress 0xe59a5719 → address
creditDataSize 0x1f1a202c → uint32
creditPriceInEuro 0xc34b6011 → uint32
getNeededTokensForBytesToCertify 0x2541e87d → uint256
issuerNbBytesToCertifyBalance 0x1b6c6c70 → uint256
nbBytesToCertify 0x9fb88144 → uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
rateBCDTETH 0xebbbcf82 → uint256
rateETHEUR 0x56aa595f → uint32
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
buyBytesToCertify 0x3db55bcb
uint32 _issuerID
uint256 _nbBytesToCertify
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
updateBCDAddress 0x75d9f4cb
address _newBCDAddress
updateBurnRate 0xecdd75d0
uint8 _newBurnRate
updateCreditDataSize 0xfe0bfc99
uint32 _creditDataSize
updateCreditPriceInEuro 0x37a3ce54
uint32 _creditPriceInEuro
updateRateBCDTETH 0xe06dd2e9
uint256 _newRateBCDTETH
updateRateETHEUR 0xd710c615
uint32 _newRateETHEUR
Recent Transactions
No transactions found for this address