Emojity es un lenguaje emoji que compila directamente a bytecode de la EVM. Es un proyecto open source en desarrollo activo gestionado por Filosofía Código y se encuentra actualmente en versión beta. La versión 0️⃣🤗0️⃣ fue lanzada recientemente y para celebrarlo se puso a disposición 1 ETH como recompensa a quién, por medio de una vulnerabilidad, rompa el contrato y logre obtener los fondos que están almacenados en un contrato escrito en Emojity.
Emojity es un lenguaje de programación para escribir smart contracts en Ethereum. Puedes pensar en Emojity como una alternativa a Solidity y Vyper, con la diferencia que escribes toda la lógica usando únicamente emojis.
¿Porqué usar Emojity? Emojity no solo es una manera más creativa y divertida de escribir smart contracts, sino que también tiene como misión ayudar a diversificar a nivel de lenguaje para que Ethereum sea más resiliente.
El contrato en cuestión es un staking simple, donde yo stakíe 0.5 ETH y solo yo debería ser capáz de sacarlo. Ahora bién, si por medio de un error (ya sea a nivel de contrato o de compilador) logras romper el contrato y obtener los fondos, esos fondos son tuyos. Y además, si escribes y publicas un artículo post mortem explicando a detalle y de manera replicable cómo realizaste el exploit, que incluya el código o método utilizado, te ganarás un premio de 0.5 ETH.
Actualmente no cuento con un programa de incentivos por desarrollo o de bug bounties general a nivel compilador pero tengo los PR e issues abiertos en github y estaré revisando las contribuciones.
Links clave:
Address del contrato lanzado en Scroll Mainnet: 0x4Eb6FFa53Ff43EaCdCAcb8813686F19AC1a97bca(Sujeto a cambio cada versión nueva de Emojity)
Documentación oficial de Emojity
Remojix, el compilador web
Repositorio en Github del compilador (¡pull requests e issues bienvenidos!)
🍇 es una variable de estado. Un hashmap que almacena el staking de cada usuario.
🍇🔼 es una función que permite a cualquier caller
(o sender) 👤 stakear ETH enviándolo como value
💰.
🍇🔽 es una función que devuelve el staking que el caller 👤
🍇❓ es una función tipo view. Devuelve el staking del address enviado como párametro 🍓
0️⃣🤗0️⃣
🗺️🍇
🍇🔼📢↩️🔢
🏁
🍇👤📥🍇👤➕💰
↩️1️⃣
🔚
🍇🔽📢↩️🔢
🏁
🔢🍓
🍓📥🍇👤
🍇👤📥0️⃣
📡👤📍0️⃣💸🍓⛽0️⃣
↩️1️⃣
🔚
🍇❓👀#️⃣🍓↩️🔢
🏁
↩️🍇🍓
🔚
A pesar que el siguiente contrato no es equivalente a nivel de bytecode, sigue la misma lógica que el contrato en del bug bounty. Puedes usarlo para guiarte y entender la lógica.
// 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];
}
}
60FE600D60003960FE6000F3FE6100076100D3565B631DE04896811461002D5763E678FF3781146100585763DBDBA63481146100B957600080FD5B3433600052600060145260346000205401336034526000604852603460342055600160685260206068F35B33602052600060345260346020205460005260003360545260006068526034605420557F00000000000000000000000000000000000000000000000000000000000000006088526000600060046000600051336000F16001608C526020608CF35B600435600052600060145260346000205460345260206034F35B60007C010000000000000000000000000000000000000000000000000000000060003504905090565BFD
[
{
"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"
}
]
Puedes usar IEmojiContract
para interactuar desde Remix, Foundry, Hardhat u otro contrato.
// 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);
}