mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	[Sol - Yul] Add support for send(..) & transfer(..)
This commit is contained in:
		
							parent
							
								
									602b29cba7
								
							
						
					
					
						commit
						a9f4d14010
					
				| @ -730,6 +730,16 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 	case FunctionType::Kind::Revert: | ||||
| 	{ | ||||
| 		solAssert(arguments.size() == parameterTypes.size(), ""); | ||||
| 		if (arguments.empty()) | ||||
| 			m_code << "revert(0, 0)\n"; | ||||
| 		else | ||||
| 			solUnimplementedAssert(false, ""); | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 	// Array creation using new
 | ||||
| 	case FunctionType::Kind::ObjectCreation: | ||||
| 	{ | ||||
| @ -908,6 +918,34 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 	case FunctionType::Kind::Send: | ||||
| 	case FunctionType::Kind::Transfer: | ||||
| 	{ | ||||
| 		solAssert(arguments.size() == 1 && parameterTypes.size() == 1, ""); | ||||
| 		string address{IRVariable(_functionCall.expression()).part("address").name()}; | ||||
| 		string value{expressionAsType(*arguments[0], *(parameterTypes[0]))}; | ||||
| 		Whiskers templ(R"( | ||||
| 			let <gas> := 0 | ||||
| 			if iszero(<value>) { <gas> := <callStipend> } | ||||
| 			let <success> := call(<gas>, <address>, <value>, 0, 0, 0, 0) | ||||
| 			<?isTransfer> | ||||
| 				if iszero(<success>) { <forwardingRevert>() } | ||||
| 			</isTransfer> | ||||
| 		)"); | ||||
| 		templ("gas", m_context.newYulVariable()); | ||||
| 		templ("callStipend", toString(evmasm::GasCosts::callStipend)); | ||||
| 		templ("address", address); | ||||
| 		templ("value", value); | ||||
| 		if (functionType->kind() == FunctionType::Kind::Transfer) | ||||
| 			templ("success", m_context.newYulVariable()); | ||||
| 		else | ||||
| 			templ("success", IRVariable(_functionCall).commaSeparatedList()); | ||||
| 		templ("isTransfer", functionType->kind() == FunctionType::Kind::Transfer); | ||||
| 		templ("forwardingRevert", m_utils.forwardingRevertFunction()); | ||||
| 		m_code << templ.render(); | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 	default: | ||||
| 		solUnimplemented("FunctionKind " + toString(static_cast<int>(functionType->kind())) + " not yet implemented"); | ||||
| 	} | ||||
|  | ||||
| @ -50,6 +50,7 @@ using namespace solidity::langutil; | ||||
| #define ALSO_VIA_YUL(CODE) \ | ||||
| { \ | ||||
| 	{ CODE } \ | ||||
| 	reset(); \ | ||||
| 	m_compileViaYul = true; \ | ||||
| 	{ CODE } \ | ||||
| } | ||||
| @ -1058,11 +1059,13 @@ BOOST_AUTO_TEST_CASE(send_ether) | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	u256 amount(130); | ||||
| 	compileAndRun(sourceCode, amount + 1); | ||||
| 	u160 address(23); | ||||
| 	ABI_CHECK(callContractFunction("a(address,uint256)", address, amount), encodeArgs(1)); | ||||
| 	BOOST_CHECK_EQUAL(balanceAt(address), amount); | ||||
| 	ALSO_VIA_YUL( | ||||
| 		u256 amount(250); | ||||
| 		compileAndRun(sourceCode, amount + 1); | ||||
| 		u160 address(23); | ||||
| 		ABI_CHECK(callContractFunction("a(address,uint256)", address, amount), encodeArgs(1)); | ||||
| 		BOOST_CHECK_EQUAL(balanceAt(address), amount); | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(transfer_ether) | ||||
| @ -1088,17 +1091,19 @@ BOOST_AUTO_TEST_CASE(transfer_ether) | ||||
| 			} | ||||
| 		} | ||||
| 	)"; | ||||
| 	compileAndRun(sourceCode, 0, "B"); | ||||
| 	u160 const nonPayableRecipient = m_contractAddress; | ||||
| 	compileAndRun(sourceCode, 0, "C"); | ||||
| 	u160 const oogRecipient = m_contractAddress; | ||||
| 	compileAndRun(sourceCode, 20, "A"); | ||||
| 	u160 payableRecipient(23); | ||||
| 	ABI_CHECK(callContractFunction("a(address,uint256)", payableRecipient, 10), encodeArgs(10)); | ||||
| 	BOOST_CHECK_EQUAL(balanceAt(payableRecipient), 10); | ||||
| 	BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10); | ||||
| 	ABI_CHECK(callContractFunction("b(address,uint256)", nonPayableRecipient, 10), encodeArgs()); | ||||
| 	ABI_CHECK(callContractFunction("b(address,uint256)", oogRecipient, 10), encodeArgs()); | ||||
| 	ALSO_VIA_YUL( | ||||
| 		compileAndRun(sourceCode, 0, "B"); | ||||
| 		u160 const nonPayableRecipient = m_contractAddress; | ||||
| 		compileAndRun(sourceCode, 0, "C"); | ||||
| 		u160 const oogRecipient = m_contractAddress; | ||||
| 		compileAndRun(sourceCode, 20, "A"); | ||||
| 		u160 payableRecipient(23); | ||||
| 		ABI_CHECK(callContractFunction("a(address,uint256)", payableRecipient, 10), encodeArgs(10)); | ||||
| 		BOOST_CHECK_EQUAL(balanceAt(payableRecipient), 10); | ||||
| 		BOOST_CHECK_EQUAL(balanceAt(m_contractAddress), 10); | ||||
| 		ABI_CHECK(callContractFunction("b(address,uint256)", nonPayableRecipient, 10), encodeArgs()); | ||||
| 		ABI_CHECK(callContractFunction("b(address,uint256)", oogRecipient, 10), encodeArgs()); | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(uncalled_blockhash) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user