Emojity is an emoji programming language that compiles directly to EVM bytecode. It's an open-source project under active development managed by Filosofia Codigo and is currently in beta version. Version 0️⃣🤗0️⃣ was recently released, and to celebrate it, 1ETH was made available as a reward to anyone who, through a vulnerability, breaks the contract and manages to obtain the funds stored in a staking contract written in Emojity.
Emojity is a programming language for writing smart contracts on Ethereum. You can think of Emojity as an alternative to Solidity and Vyper, with the difference being that you write all the logic using only emojis.
Why use Emojity? Emojity is not only a more creative and fun way to write smart contracts but also aims to help diversify Ethereum at language level to make it more resilient.
The bug bounty is about breaking a simple staking contract written in Emojity. In that contract I staked 0.5 ETH and only I should be able to withdraw it. However, if you manage to break the contract and obtain the funds through an error (whether at the contract or compiler level), those funds are yours. Furthermore, if you write and publish a post-mortem article explaining in detail how you performed the exploit and how to replicate it, including the code or method used, you'll earn a prize of 0.5 ETH.
Currently, I don’t have a development incentive or bug bounty program at the compiler level, but I have open PRs and issues on github, and I will be reviewing all contributions.
Key links:
Contract address deployed in Scroll Mainnet: 0x4Eb6FFa53Ff43EaCdCAcb8813686F19AC1a97bca (Might change each Solidity version)
Emojity Official documentation
Remojix, the web compiler
Compiler github repo (pull requests and issues welcome!)
🍇 is a state variable. A hashmap that stores each user’s stake balance.
🍇🔼 is a function that allows any
caller(or sender) 👤 stake ETH by sending it asvalue💰.🍇🔽 es a function that returns the caller’s 👤 stake
🍇❓ is a view function. Returns the stake of the address sent as parameter 🍓
0️⃣🤗0️⃣
🗺️🍇
🍇🔼📢↩️🔢
🏁
🍇👤📥🍇👤➕💰
↩️1️⃣
🔚
🍇🔽📢↩️🔢
🏁
🔢🍓
🍓📥🍇👤
🍇👤📥0️⃣
📡👤📍0️⃣💸🍓⛽0️⃣
↩️1️⃣
🔚
🍇❓👀#️⃣🍓↩️🔢
🏁
↩️🍇🍓
🔚
Even though the following contract is not equivalent at the bytecode level, it follows the same logic as the contract in the bug bounty. You can use it as a guide to understand the logic.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
contract StakingContract {
mapping(address account => uint balance) stakeBalance;
function stake() public payable returns(bool success) {
stakeBalance[msg.sender] += msg.value;
return true;
}
function unstake() public returns(bool success) {
uint senderStake = stakeBalance[msg.sender];
stakeBalance[msg.sender] = 0;
(bool sent, bytes memory data) = msg.sender.call{value: senderStake}("");
data;
return sent;
}
function getStake(address account) public view returns(uint balance) {
return stakeBalance[account];
}
}
[ { "inputs":[ ],
"name":"grapesUpwardsButton",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"nonpayable",
"type":"function"
},
{
"inputs":[
],
"name":"grapesDownwardsButton",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"nonpayable",
"type":"function"
},
{
"inputs":[
{
"name":"strawberry",
"type":"address"
}
],
"name":"grapesQuestionMark",
"outputs":[
{
"internalType":"uint256",
"name":"",
"type":"uint256"
}
],
"stateMutability":"view",
"type":"function"
}
]
You can use IEmojiContract to interact from Remix, Foundry, Hardhat or from another contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IEmojiContract {
function grapesUpwardsButton() external returns (uint256);
function grapesDownwardsButton() external returns (uint256);
function grapesQuestionMark(address strawberry) external view returns (uint256);
}
